[Pkg-cli-apps-commits] [fsharp] 09/60: Open sourcing the IDE unit tests (changeset 1294310)

Christopher Halse Rogers raof-guest at moszumanska.debian.org
Sun Sep 14 08:13:35 UTC 2014


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

raof-guest pushed a commit to branch master
in repository fsharp.

commit 64109c51484a0c2b421c219108bd0835c576f0de
Author: latkin <latkin at microsoft.com>
Date:   Wed Jul 9 11:55:40 2014 -0700

    Open sourcing the IDE unit tests (changeset 1294310)
---
 DEVGUIDE.html                                      |    3 +-
 src/FSharpSource.targets                           |    4 +-
 src/fsharp/FSharp.Build/FSharp.Build.fsproj        |    1 +
 src/fsharp/FSharp.Build/InternalsVisibleTo.fs      |    9 +
 src/fsharp/FSharp.Build/subst.exe                  |  Bin 941568 -> 1374720 bytes
 src/fsharp/FSharp.Build/subst.fsx                  |   32 +-
 .../FSharp.Compiler.Interactive.Settings.fsproj    |    1 +
 .../InternalsVisibleTo.fs                          |   10 +
 .../FSharp.Compiler.Server.Shared.fsproj           |    1 +
 .../InternalsVisibleTo.fs                          |   10 +
 src/fsharp/FSharp.Compiler/InternalsVisibleTo.fs   |   21 +-
 .../FSharp.LanguageService.Compiler.fsproj         |    1 +
 .../InternalsVisibleTo.fs                          |   22 +
 src/fsharp/Fsc/Fsc.fsproj                          |    1 +
 src/fsharp/Fsc/InternalsVisibleTo.fs               |    8 +
 tests/RunTests.cmd                                 |   24 +-
 tests/TESTGUIDE.html                               |   38 +-
 vsintegration/fsharp-vsintegration-build.proj      |   13 +
 .../fsharp-vsintegration-unittests-build.proj      |   26 +
 vsintegration/src/Salsa/InternalsVisibleTo.fs      |   10 +
 vsintegration/src/Salsa/Salsa.fsproj               |  107 +
 vsintegration/src/Salsa/SalsaUtils.fs              |  347 +
 vsintegration/src/Salsa/SalsaUtils.fsi             |  143 +
 vsintegration/src/Salsa/VsMocks.fs                 | 1685 +++++
 vsintegration/src/Salsa/salsa.fs                   | 1714 +++++
 vsintegration/src/Salsa/salsa.fsi                  |  222 +
 .../ArtificalEventInfo.cs                          |  120 +
 .../ArtificialConstructorInfo.cs                   |  124 +
 .../ArtificialMethodInfo.cs                        |  152 +
 .../ArtificialParamInfo.cs                         |  144 +
 .../ArtificialPropertyInfo.cs                      |  166 +
 .../DefinitionLocationAttribute/ArtificialType.cs  |  744 ++
 .../DefinitionLocationAttribute.csproj             |   43 +
 .../TypeProviderInCSharp.cs                        |  150 +
 .../ArtificalEventInfo.cs                          |  130 +
 .../ArtificialConstructorInfo.cs                   |  135 +
 .../ArtificialMethodInfo.cs                        |  168 +
 .../ArtificialParamInfo.cs                         |  156 +
 .../ArtificialPropertyInfo.cs                      |  180 +
 .../ArtificialType.cs                              |  769 ++
 ...initionLocationAttributeFileDoesnotExist.csproj |   41 +
 .../TypeProviderInCSharp.cs                        |  150 +
 .../ArtificalEventInfo.cs                          |  129 +
 .../ArtificialConstructorInfo.cs                   |  135 +
 .../ArtificialMethodInfo.cs                        |  168 +
 .../ArtificialParamInfo.cs                         |  156 +
 .../ArtificialPropertyInfo.cs                      |  181 +
 .../ArtificialType.cs                              |  771 ++
 ...initionLocationAttributeLineDoesnotExist.csproj |   41 +
 .../TypeProviderInCSharp.cs                        |  140 +
 .../ArtificalEventInfo.cs                          |  131 +
 .../ArtificialConstructorInfo.cs                   |  135 +
 .../ArtificialMethodInfo.cs                        |  168 +
 .../ArtificialParamInfo.cs                         |  156 +
 .../ArtificialPropertyInfo.cs                      |  181 +
 .../ArtificialType.cs                              |  771 ++
 ...itionLocationAttributeWithSpaceInTheType.csproj |   42 +
 .../TypeProviderInCSharp.cs                        |  141 +
 .../DummyProviderForLanguageServiceTesting.fs      |  426 ++
 .../DummyProviderForLanguageServiceTesting.fsproj  |   43 +
 .../TypeProviderEmit.fs                            | 1495 ++++
 .../TypeProviderEmit.fsi                           |  283 +
 .../ArtificalEventInfo.cs                          |  130 +
 .../ArtificialConstructorInfo.cs                   |  135 +
 .../ArtificialMethodInfo.cs                        |  168 +
 .../ArtificialParamInfo.cs                         |  156 +
 .../ArtificialPropertyInfo.cs                      |  180 +
 .../EditorHideMethodsAttribute/ArtificialType.cs   |  769 ++
 .../EditorHideMethodsAttribute.csproj              |   41 +
 .../TypeProviderInCSharp.cs                        |  150 +
 .../EmptyAssembly/EmptyAssembly.fs                 |   10 +
 .../EmptyAssembly/EmptyAssembly.fsproj             |   41 +
 .../Resources.MockTypeProviders/Helpers.cs         |   58 +
 .../ArtificalEventInfo.cs                          |  130 +
 .../ArtificialConstructorInfo.cs                   |  135 +
 .../ArtificialMethodInfo.cs                        |  168 +
 .../ArtificialParamInfo.cs                         |  157 +
 .../ArtificialPropertyInfo.cs                      |  181 +
 .../ArtificialType.cs                              |  768 ++
 .../TypeProviderInCSharp.cs                        |  150 +
 .../XmlDocAttributeWithAdequateComment.csproj      |   41 +
 .../ArtificalEventInfo.cs                          |  130 +
 .../ArtificialConstructorInfo.cs                   |  135 +
 .../ArtificialMethodInfo.cs                        |  168 +
 .../ArtificialParamInfo.cs                         |  156 +
 .../ArtificialPropertyInfo.cs                      |  181 +
 .../ArtificialType.cs                              |  768 ++
 .../TypeProviderInCSharp.cs                        |  150 +
 .../XmlDocAttributeWithEmptyComment.csproj         |   41 +
 .../ArtificalEventInfo.cs                          |  129 +
 .../ArtificialConstructorInfo.cs                   |  134 +
 .../ArtificialMethodInfo.cs                        |  167 +
 .../ArtificialParamInfo.cs                         |  155 +
 .../ArtificialPropertyInfo.cs                      |  179 +
 .../ArtificialType.cs                              |  767 ++
 .../TypeProviderInCSharp.cs                        |  150 +
 .../XmlDocAttributeWithLocalizedComment.csproj     |   41 +
 .../ArtificalEventInfo.cs                          |  129 +
 .../ArtificialConstructorInfo.cs                   |  134 +
 .../ArtificialMethodInfo.cs                        |  168 +
 .../ArtificialParamInfo.cs                         |  154 +
 .../ArtificialPropertyInfo.cs                      |  180 +
 .../ArtificialType.cs                              |  767 ++
 .../TypeProviderInCSharp.cs                        |  150 +
 .../XmlDocAttributeWithLongComment.csproj          |   41 +
 .../ArtificalEventInfo.cs                          |  129 +
 .../ArtificialConstructorInfo.cs                   |  135 +
 .../ArtificialMethodInfo.cs                        |  168 +
 .../ArtificialParamInfo.cs                         |  155 +
 .../ArtificialPropertyInfo.cs                      |  179 +
 .../ArtificialType.cs                              |  767 ++
 .../TypeProviderInCSharp.cs                        |  150 +
 .../XmlDocAttributeWithNullComment.csproj          |   41 +
 .../Resources/TestTypeProvider.Negative1.fsx       |   39 +
 .../Resources/TestTypeProvider.Positive1.fsx       |   99 +
 .../src/unittests/TestLib.LanguageService.fs       |  476 ++
 .../src/unittests/TestLib.ProjectSystem.fs         |  720 ++
 vsintegration/src/unittests/TestLib.Salsa.fs       |  127 +
 vsintegration/src/unittests/TestLib.Utils.fs       |  355 +
 vsintegration/src/unittests/Tests.BaseLine.fs      |   58 +
 vsintegration/src/unittests/Tests.Build.fs         |  466 ++
 .../src/unittests/Tests.InternalCollections.fs     |  216 +
 .../unittests/Tests.LanguageService.Colorizer.fs   | 1077 +++
 .../unittests/Tests.LanguageService.Completion.fs  | 7610 ++++++++++++++++++++
 .../unittests/Tests.LanguageService.ErrorList.fs   |  948 +++
 .../Tests.LanguageService.ErrorRecovery.fs         |  286 +
 .../unittests/Tests.LanguageService.F1Keyword.fs   |  392 +
 .../src/unittests/Tests.LanguageService.General.fs |  605 ++
 .../Tests.LanguageService.GotoDefinition.fs        | 1457 ++++
 .../Tests.LanguageService.IncrementalBuild.fs      |  580 ++
 .../Tests.LanguageService.NavigationBar.fs         |  239 +
 .../Tests.LanguageService.ParameterInfo.fs         | 2265 ++++++
 .../unittests/Tests.LanguageService.QuickInfo.fs   | 3654 ++++++++++
 .../unittests/Tests.LanguageService.QuickParse.fs  |  171 +
 .../src/unittests/Tests.LanguageService.Script.fs  | 1641 +++++
 .../unittests/Tests.LanguageService.Squiggles.fs   | 1020 +++
 .../unittests/Tests.LanguageService.TimeStamp.fs   |  332 +
 vsintegration/src/unittests/Tests.Powerpack.fs     |   88 +
 .../src/unittests/Tests.ProjectSystem.Configs.fs   |  212 +
 .../unittests/Tests.ProjectSystem.Miscellaneous.fs |  839 +++
 .../Tests.ProjectSystem.MultiTargeting.fs          |  166 +
 .../src/unittests/Tests.ProjectSystem.Project.fs   |  817 +++
 .../unittests/Tests.ProjectSystem.ProjectItems.fs  |  165 +
 .../unittests/Tests.ProjectSystem.References.fs    |  621 ++
 .../src/unittests/Tests.ProjectSystem.RoundTrip.fs |  140 +
 vsintegration/src/unittests/Tests.TaskReporter.fs  |  369 +
 .../src/unittests/Tests.TypeProvidersImpl.fs       |  374 +
 vsintegration/src/unittests/Tests.Watson.fs        |  169 +
 .../src/unittests/Tests.XmlDocComments.fs          |  102 +
 vsintegration/src/unittests/Unittests.dll.config   |   37 +
 vsintegration/src/unittests/Unittests.fsproj       |  170 +
 .../CodeWindowManager.cs                           |    2 +
 .../src/vs/FsPkgs/FSharp.LanguageService/Source.fs |    2 +
 .../Project/Automation/OAFileItem.cs               |   11 +-
 .../CodeGeneratorRegistrationAttribute.cs          |   11 +-
 .../ComponentPickerPropertyPageAttribute.cs        |   11 +-
 .../EditorFactoryNotifyForProjectAttribute.cs      |   11 +-
 .../vs/FsPkgs/FSharp.Project/FS/AppConfigHelper.fs |    5 +-
 .../FS/FSharp.ProjectSystem.FSharp.dll.config      |    1 +
 .../FsPkgs/FSharp.Project/FS/InternalsVisibleTo.fs |   19 +-
 .../vs/FsPkgs/FSharp.VS.FSI/InternalsVisibleTo.fs  |    2 +
 .../src/vs/FsPkgs/FSharp.VS.FSI/VSPackage.resx     |    1 +
 .../src/vs/FsPkgs/FSharp.VS.FSI/fsiPackageHooks.fs |    3 +-
 vsintegration/src/vs/FsPkgs/common.fs              |    2 +
 164 files changed, 53084 insertions(+), 83 deletions(-)

diff --git a/DEVGUIDE.html b/DEVGUIDE.html
index 0450389..cf53e59 100644
--- a/DEVGUIDE.html
+++ b/DEVGUIDE.html
@@ -425,7 +425,8 @@
         To build the VS components:
     </p>
     <pre>
-        msbuild ..\vsintegration\src\deployment.sln /p:Configuration=Debug /t:Rebuild
+        cd ..\vsintegration
+        msbuild fsharp-vsintegration-build.proj
     </pre>
 
     <h3>6. [Optional] Build and install Visual Studio components </h3>
diff --git a/src/FSharpSource.targets b/src/FSharpSource.targets
index 6fc1621..55a93c5 100644
--- a/src/FSharpSource.targets
+++ b/src/FSharpSource.targets
@@ -611,7 +611,7 @@
 
     <FscToolPath>$(FSharpSourcesRoot)\..\Proto\$(protoCLIDir)\bin</FscToolPath>
     <FscToolExe>fsc-proto.exe</FscToolExe>
-    <OutputPath>$(FSharpSourcesRoot)\..\$(Configuration)\$(TargetFramework)\bin</OutputPath>
+    <OutputPath Condition=" '$(CustomOutputPath)' != 'true' ">$(FSharpSourcesRoot)\..\$(Configuration)\$(TargetFramework)\bin</OutputPath>
   </PropertyGroup>
 
   <Choose>
@@ -709,7 +709,7 @@
           Outputs="@(CustomCopyLocal->'$(OutDir)%(TargetFilename)')"
           Condition="'$(targetCLIDir)'!='Silverlight/4.0/'"
                 >
-    <Exec Command="$(FSharpSourcesRoot)\fsharp\FSharp.Build\subst.exe {LkgVersion} $(LkgVersion) {BuildSuffix} "$(FsBuildSuffix)" {FSharpTargetsDir} "%24(MSBuildThisFileDirectory)" "%(CustomCopyLocal.FullPath)" > $(OutDir)%(CustomCopyLocal.TargetFilename)  "/>
+    <Exec Command="$(FSharpSourcesRoot)\fsharp\FSharp.Build\subst.exe "%(CustomCopyLocal.FullPath)" {FinalDir} "$([System.IO.Path]::GetFullPath('$(OutputPath)'))\" {LkgVersion} $(LkgVersion) {BuildSuffix} "$(FsBuildSuffix)" {FSharpTargetsDir} "%24(MSBuildThisFileDirectory)" > $(OutDir)%(CustomCopyLocal.TargetFilename)  "/>
     <!-- Make sure it will get cleaned  -->
     <CreateItem Include="$(OutDir)%(CustomCopyLocal.TargetFilename)">
       <Output TaskParameter="Include" ItemName="FileWrites"/>
diff --git a/src/fsharp/FSharp.Build/FSharp.Build.fsproj b/src/fsharp/FSharp.Build/FSharp.Build.fsproj
index c49bb96..5c1898e 100644
--- a/src/fsharp/FSharp.Build/FSharp.Build.fsproj
+++ b/src/fsharp/FSharp.Build/FSharp.Build.fsproj
@@ -17,6 +17,7 @@
       <FsSrGen Include="FSBuild.txt">
         <Link>FSBuild.txt</Link>
       </FsSrGen>
+    <Compile Include="InternalsVisibleTo.fs" />
     <Compile Include="..\..\assemblyinfo\assemblyinfo.FSharp.Build.dll.fs">
       <Link>assemblyinfo.FSharp.Build.dll.fs</Link>
     </Compile>
diff --git a/src/fsharp/FSharp.Build/InternalsVisibleTo.fs b/src/fsharp/FSharp.Build/InternalsVisibleTo.fs
new file mode 100644
index 0000000..df3ab05
--- /dev/null
+++ b/src/fsharp/FSharp.Build/InternalsVisibleTo.fs
@@ -0,0 +1,9 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+namespace Microsoft.FSharp
+open System.Reflection
+[<assembly:System.Runtime.CompilerServices.InternalsVisibleTo("Unittests, PublicKey=002400000480000094000000060200000024000052534131000400000100010007D1FA57C4AED9F0A32E84AA0FAEFD0DE9E8FD6AEC8F87FB03766C834C99921EB23BE79AD9D5DCC1DD9AD236132102900B723CF980957FC4E177108FC607774F29E8320E92EA05ECE4E821C0A5EFE8F1645C4C0C93C1AB99285D622CAA652C1DFAD63D745D6F2DE5F17E5EAF0FC4963D261C8A12436518206DC093344D5AD293")>]
+
+
+do()
+
diff --git a/src/fsharp/FSharp.Build/subst.exe b/src/fsharp/FSharp.Build/subst.exe
index 8da1e54..b39cd76 100644
Binary files a/src/fsharp/FSharp.Build/subst.exe and b/src/fsharp/FSharp.Build/subst.exe differ
diff --git a/src/fsharp/FSharp.Build/subst.fsx b/src/fsharp/FSharp.Build/subst.fsx
index 91bab29..fcf2c98 100644
--- a/src/fsharp/FSharp.Build/subst.fsx
+++ b/src/fsharp/FSharp.Build/subst.fsx
@@ -1,16 +1,22 @@
 // Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
 
-let x1,y1,x2,y2,x3,y3,file = 
-   match System.Environment.GetCommandLineArgs() with 
-   | [| _; x1;y1;x2;y2;x3;y3;file |] -> x1,y1,x2,y2,x3,y3,file
-   | _ -> 
-       eprintfn "Invalid command line args. usage 'subst.exe origtext1 replacetext1 origtext2 replacetext2 origtext3 replacetext3 file'"
-       exit 1 
-   
-file 
-   |> System.IO.File.ReadAllText 
-   |> (fun s -> s.Replace(x1,y1)) 
-   |> (fun s -> s.Replace(x2,y2)) 
-   |> (fun s -> s.Replace(x3,y3)) 
-   |> printfn "%s"
+open System.IO
+ 
+module Seq =
+    let evens s = s |> Seq.mapi (fun i x -> (i, x)) |> Seq.choose (function (i, x) when i % 2 = 0 -> Some(x) | _ -> None)
+    let odds  s = s |> Seq.mapi (fun i x -> (i, x)) |> Seq.choose (function (i, x) when i % 2 = 1 -> Some(x) | _ -> None)
+    
+let rawArgs = System.Environment.GetCommandLineArgs()
+
+if rawArgs.Length < 4 || rawArgs.Length % 2 <> 0 then
+    eprintfn "Invalid command line args. usage 'subst.exe file origtext1 replacetext1 ... origtextN replacetextN'"
+    exit 1
+else
+
+(rawArgs |> Seq.evens, rawArgs |> Seq.odds)
+||> Seq.zip
+|> Seq.skip 1
+|> Seq.fold (fun (content:string) (orig, replace) -> content.Replace(orig, replace)) (File.ReadAllText(rawArgs.[1]))
+|> printfn "%s"
+  
 exit 0
\ No newline at end of file
diff --git a/src/fsharp/FSharp.Compiler.Interactive.Settings/FSharp.Compiler.Interactive.Settings.fsproj b/src/fsharp/FSharp.Compiler.Interactive.Settings/FSharp.Compiler.Interactive.Settings.fsproj
index 99b9ea0..63ae670 100644
--- a/src/fsharp/FSharp.Compiler.Interactive.Settings/FSharp.Compiler.Interactive.Settings.fsproj
+++ b/src/fsharp/FSharp.Compiler.Interactive.Settings/FSharp.Compiler.Interactive.Settings.fsproj
@@ -18,6 +18,7 @@
       <FsSrGen Include="..\FSInteractiveSettings.txt">
         <Link>FSInteractiveSettings.txt</Link>
       </FsSrGen>
+    <Compile Include="InternalsVisibleTo.fs"/>
     <Compile Include="..\..\assemblyinfo\assemblyinfo.FSharp.Compiler.Interactive.Settings.dll.fs">
       <Link>assemblyinfo.FSharp.Compiler.Interactive.Settings.dll.fs</Link>
     </Compile>
diff --git a/src/fsharp/FSharp.Compiler.Interactive.Settings/InternalsVisibleTo.fs b/src/fsharp/FSharp.Compiler.Interactive.Settings/InternalsVisibleTo.fs
new file mode 100644
index 0000000..2910533
--- /dev/null
+++ b/src/fsharp/FSharp.Compiler.Interactive.Settings/InternalsVisibleTo.fs
@@ -0,0 +1,10 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+namespace Microsoft.FSharp
+open System.Reflection
+[<assembly:System.Runtime.CompilerServices.InternalsVisibleTo("Fsi, PublicKey=002400000480000094000000060200000024000052534131000400000100010007D1FA57C4AED9F0A32E84AA0FAEFD0DE9E8FD6AEC8F87FB03766C834C99921EB23BE79AD9D5DCC1DD9AD236132102900B723CF980957FC4E177108FC607774F29E8320E92EA05ECE4E821C0A5EFE8F1645C4C0C93C1AB99285D622CAA652C1DFAD63D745D6F2DE5F17E5EAF0FC4963D261C8A12436518206DC093344D5AD293")>]
+[<assembly:System.Runtime.CompilerServices.InternalsVisibleTo("FsiAnyCPU, PublicKey=002400000480000094000000060200000024000052534131000400000100010007D1FA57C4AED9F0A32E84AA0FAEFD0DE9E8FD6AEC8F87FB03766C834C99921EB23BE79AD9D5DCC1DD9AD236132102900B723CF980957FC4E177108FC607774F29E8320E92EA05ECE4E821C0A5EFE8F1645C4C0C93C1AB99285D622CAA652C1DFAD63D745D6F2DE5F17E5EAF0FC4963D261C8A12436518206DC093344D5AD293")>]
+[<assembly:System.Runtime.CompilerServices.InternalsVisibleTo("FSharp.Compiler, PublicKey=002400000480000094000000060200000024000052534131000400000100010007D1FA57C4AED9F0A32E84AA0FAEFD0DE9E8FD6AEC8F87FB03766C834C99921EB23BE79AD9D5DCC1DD9AD236132102900B723CF980957FC4E177108FC607774F29E8320E92EA05ECE4E821C0A5EFE8F1645C4C0C93C1AB99285D622CAA652C1DFAD63D745D6F2DE5F17E5EAF0FC4963D261C8A12436518206DC093344D5AD293")>]
+
+do()
+
diff --git a/src/fsharp/FSharp.Compiler.Server.Shared/FSharp.Compiler.Server.Shared.fsproj b/src/fsharp/FSharp.Compiler.Server.Shared/FSharp.Compiler.Server.Shared.fsproj
index f2d5225..92264b3 100644
--- a/src/fsharp/FSharp.Compiler.Server.Shared/FSharp.Compiler.Server.Shared.fsproj
+++ b/src/fsharp/FSharp.Compiler.Server.Shared/FSharp.Compiler.Server.Shared.fsproj
@@ -17,6 +17,7 @@
       <FsSrGen Include="..\fsiserver\FSServerShared.txt">
         <Link>FSServerShared.txt</Link>
       </FsSrGen>
+    <Compile Include="InternalsVisibleTo.fs" />
     <Compile Include="..\..\assemblyinfo\assemblyinfo.FSharp.Compiler.Server.Shared.dll.fs">
       <Link>assemblyinfo.FSharp.Compiler.Server.Shared.dll.fs</Link>
     </Compile>
diff --git a/src/fsharp/FSharp.Compiler.Server.Shared/InternalsVisibleTo.fs b/src/fsharp/FSharp.Compiler.Server.Shared/InternalsVisibleTo.fs
new file mode 100644
index 0000000..61407f1
--- /dev/null
+++ b/src/fsharp/FSharp.Compiler.Server.Shared/InternalsVisibleTo.fs
@@ -0,0 +1,10 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+namespace Microsoft.FSharp
+open System.Reflection
+[<assembly:System.Runtime.CompilerServices.InternalsVisibleTo("Fsi, PublicKey=002400000480000094000000060200000024000052534131000400000100010007D1FA57C4AED9F0A32E84AA0FAEFD0DE9E8FD6AEC8F87FB03766C834C99921EB23BE79AD9D5DCC1DD9AD236132102900B723CF980957FC4E177108FC607774F29E8320E92EA05ECE4E821C0A5EFE8F1645C4C0C93C1AB99285D622CAA652C1DFAD63D745D6F2DE5F17E5EAF0FC4963D261C8A12436518206DC093344D5AD293")>]
+[<assembly:System.Runtime.CompilerServices.InternalsVisibleTo("FsiAnyCPU, PublicKey=002400000480000094000000060200000024000052534131000400000100010007D1FA57C4AED9F0A32E84AA0FAEFD0DE9E8FD6AEC8F87FB03766C834C99921EB23BE79AD9D5DCC1DD9AD236132102900B723CF980957FC4E177108FC607774F29E8320E92EA05ECE4E821C0A5EFE8F1645C4C0C93C1AB99285D622CAA652C1DFAD63D745D6F2DE5F17E5EAF0FC4963D261C8A12436518206DC093344D5AD293")>]
+[<assembly:System.Runtime.CompilerServices.InternalsVisibleTo("FSharp.VS.FSI, PublicKey=002400000480000094000000060200000024000052534131000400000100010007D1FA57C4AED9F0A32E84AA0FAEFD0DE9E8FD6AEC8F87FB03766C834C99921EB23BE79AD9D5DCC1DD9AD236132102900B723CF980957FC4E177108FC607774F29E8320E92EA05ECE4E821C0A5EFE8F1645C4C0C93C1AB99285D622CAA652C1DFAD63D745D6F2DE5F17E5EAF0FC4963D261C8A12436518206DC093344D5AD293")>]
+
+do()
+
diff --git a/src/fsharp/FSharp.Compiler/InternalsVisibleTo.fs b/src/fsharp/FSharp.Compiler/InternalsVisibleTo.fs
index 4b74296..b77e12a 100644
--- a/src/fsharp/FSharp.Compiler/InternalsVisibleTo.fs
+++ b/src/fsharp/FSharp.Compiler/InternalsVisibleTo.fs
@@ -1,6 +1,23 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
 namespace Microsoft.FSharp
 open System.Reflection
-
+[<assembly:System.Runtime.CompilerServices.InternalsVisibleTo("Fsc, PublicKey=002400000480000094000000060200000024000052534131000400000100010007D1FA57C4AED9F0A32E84AA0FAEFD0DE9E8FD6AEC8F87FB03766C834C99921EB23BE79AD9D5DCC1DD9AD236132102900B723CF980957FC4E177108FC607774F29E8320E92EA05ECE4E821C0A5EFE8F1645C4C0C93C1AB99285D622CAA652C1DFAD63D745D6F2DE5F17E5EAF0FC4963D261C8A12436518206DC093344D5AD293")>]
+[<assembly:System.Runtime.CompilerServices.InternalsVisibleTo("FSharp.Build, PublicKey=002400000480000094000000060200000024000052534131000400000100010007D1FA57C4AED9F0A32E84AA0FAEFD0DE9E8FD6AEC8F87FB03766C834C99921EB23BE79AD9D5DCC1DD9AD236132102900B723CF980957FC4E177108FC607774F29E8320E92EA05ECE4E821C0A5EFE8F1645C4C0C93C1AB99285D622CAA652C1DFAD63D745D6F2DE5F17E5EAF0FC4963D261C8A12436518206DC093344D5AD293")>]
+[<assembly:System.Runtime.CompilerServices.InternalsVisibleTo("FSharp.QuickSearch, PublicKey=002400000480000094000000060200000024000052534131000400000100010007D1FA57C4AED9F0A32E84AA0FAEFD0DE9E8FD6AEC8F87FB03766C834C99921EB23BE79AD9D5DCC1DD9AD236132102900B723CF980957FC4E177108FC607774F29E8320E92EA05ECE4E821C0A5EFE8F1645C4C0C93C1AB99285D622CAA652C1DFAD63D745D6F2DE5F17E5EAF0FC4963D261C8A12436518206DC093344D5AD293")>]
+[<assembly:System.Runtime.CompilerServices.InternalsVisibleTo("FSharp.Compiler.Model, PublicKey=002400000480000094000000060200000024000052534131000400000100010007D1FA57C4AED9F0A32E84AA0FAEFD0DE9E8FD6AEC8F87FB03766C834C99921EB23BE79AD9D5DCC1DD9AD236132102900B723CF980957FC4E177108FC607774F29E8320E92EA05ECE4E821C0A5EFE8F1645C4C0C93C1AB99285D622CAA652C1DFAD63D745D6F2DE5F17E5EAF0FC4963D261C8A12436518206DC093344D5AD293")>]
+[<assembly:System.Runtime.CompilerServices.InternalsVisibleTo("Fsi, PublicKey=002400000480000094000000060200000024000052534131000400000100010007D1FA57C4AED9F0A32E84AA0FAEFD0DE9E8FD6AEC8F87FB03766C834C99921EB23BE79AD9D5DCC1DD9AD236132102900B723CF980957FC4E177108FC607774F29E8320E92EA05ECE4E821C0A5EFE8F1645C4C0C93C1AB99285D622CAA652C1DFAD63D745D6F2DE5F17E5EAF0FC4963D261C8A12436518206DC093344D5AD293")>]
+[<assembly:System.Runtime.CompilerServices.InternalsVisibleTo("FsiAnyCPU, PublicKey=002400000480000094000000060200000024000052534131000400000100010007D1FA57C4AED9F0A32E84AA0FAEFD0DE9E8FD6AEC8F87FB03766C834C99921EB23BE79AD9D5DCC1DD9AD236132102900B723CF980957FC4E177108FC607774F29E8320E92EA05ECE4E821C0A5EFE8F1645C4C0C93C1AB99285D622CAA652C1DFAD63D745D6F2DE5F17E5EAF0FC4963D261C8A12436518206DC093344D5AD293")>]
+[<assembly:System.Runtime.CompilerServices.InternalsVisibleTo("FSharp.LanguageService, PublicKey=002400000480000094000000060200000024000052534131000400000100010007D1FA57C4AED9F0A32E84AA0FAEFD0DE9E8FD6AEC8F87FB03766C834C99921EB23BE79AD9D5DCC1DD9AD236132102900B723CF980957FC4E177108FC607774F29E8320E92EA05ECE4E821C0A5EFE8F1645C4C0C93C1AB99285D622CAA652C1DFAD63D745D6F2DE5F17E5EAF0FC4963D261C8A12436518206DC093344D5AD293")>]
+[<assembly:System.Runtime.CompilerServices.InternalsVisibleTo("FSharp.LanguageService.Base, PublicKey=002400000480000094000000060200000024000052534131000400000100010007D1FA57C4AED9F0A32E84AA0FAEFD0DE9E8FD6AEC8F87FB03766C834C99921EB23BE79AD9D5DCC1DD9AD236132102900B723CF980957FC4E177108FC607774F29E8320E92EA05ECE4E821C0A5EFE8F1645C4C0C93C1AB99285D622CAA652C1DFAD63D745D6F2DE5F17E5EAF0FC4963D261C8A12436518206DC093344D5AD293")>]
+[<assembly:System.Runtime.CompilerServices.InternalsVisibleTo("FSharp.ProjectSystem.Base, PublicKey=002400000480000094000000060200000024000052534131000400000100010007D1FA57C4AED9F0A32E84AA0FAEFD0DE9E8FD6AEC8F87FB03766C834C99921EB23BE79AD9D5DCC1DD9AD236132102900B723CF980957FC4E177108FC607774F29E8320E92EA05ECE4E821C0A5EFE8F1645C4C0C93C1AB99285D622CAA652C1DFAD63D745D6F2DE5F17E5EAF0FC4963D261C8A12436518206DC093344D5AD293")>]
+[<assembly:System.Runtime.CompilerServices.InternalsVisibleTo("FSharp.ProjectSystem.FSharp, PublicKey=002400000480000094000000060200000024000052534131000400000100010007D1FA57C4AED9F0A32E84AA0FAEFD0DE9E8FD6AEC8F87FB03766C834C99921EB23BE79AD9D5DCC1DD9AD236132102900B723CF980957FC4E177108FC607774F29E8320E92EA05ECE4E821C0A5EFE8F1645C4C0C93C1AB99285D622CAA652C1DFAD63D745D6F2DE5F17E5EAF0FC4963D261C8A12436518206DC093344D5AD293")>]
+[<assembly:System.Runtime.CompilerServices.InternalsVisibleTo("FSharp.ProjectSystem.PropertyPages, PublicKey=002400000480000094000000060200000024000052534131000400000100010007D1FA57C4AED9F0A32E84AA0FAEFD0DE9E8FD6AEC8F87FB03766C834C99921EB23BE79AD9D5DCC1DD9AD236132102900B723CF980957FC4E177108FC607774F29E8320E92EA05ECE4E821C0A5EFE8F1645C4C0C93C1AB99285D622CAA652C1DFAD63D745D6F2DE5F17E5EAF0FC4963D261C8A12436518206DC093344D5AD293")>]
+[<assembly:System.Runtime.CompilerServices.InternalsVisibleTo("FSharp.Compiler.Interactive.Settings, PublicKey=002400000480000094000000060200000024000052534131000400000100010007D1FA57C4AED9F0A32E84AA0FAEFD0DE9E8FD6AEC8F87FB03766C834C99921EB23BE79AD9D5DCC1DD9AD236132102900B723CF980957FC4E177108FC607774F29E8320E92EA05ECE4E821C0A5EFE8F1645C4C0C93C1AB99285D622CAA652C1DFAD63D745D6F2DE5F17E5EAF0FC4963D261C8A12436518206DC093344D5AD293")>]
+[<assembly:System.Runtime.CompilerServices.InternalsVisibleTo("FSharp.Compiler.Server.Shared, PublicKey=002400000480000094000000060200000024000052534131000400000100010007D1FA57C4AED9F0A32E84AA0FAEFD0DE9E8FD6AEC8F87FB03766C834C99921EB23BE79AD9D5DCC1DD9AD236132102900B723CF980957FC4E177108FC607774F29E8320E92EA05ECE4E821C0A5EFE8F1645C4C0C93C1AB99285D622CAA652C1DFAD63D745D6F2DE5F17E5EAF0FC4963D261C8A12436518206DC093344D5AD293")>]
+[<assembly:System.Runtime.CompilerServices.InternalsVisibleTo("Salsa, PublicKey=002400000480000094000000060200000024000052534131000400000100010007D1FA57C4AED9F0A32E84AA0FAEFD0DE9E8FD6AEC8F87FB03766C834C99921EB23BE79AD9D5DCC1DD9AD236132102900B723CF980957FC4E177108FC607774F29E8320E92EA05ECE4E821C0A5EFE8F1645C4C0C93C1AB99285D622CAA652C1DFAD63D745D6F2DE5F17E5EAF0FC4963D261C8A12436518206DC093344D5AD293")>]
+[<assembly:System.Runtime.CompilerServices.InternalsVisibleTo("Unittests, PublicKey=002400000480000094000000060200000024000052534131000400000100010007D1FA57C4AED9F0A32E84AA0FAEFD0DE9E8FD6AEC8F87FB03766C834C99921EB23BE79AD9D5DCC1DD9AD236132102900B723CF980957FC4E177108FC607774F29E8320E92EA05ECE4E821C0A5EFE8F1645C4C0C93C1AB99285D622CAA652C1DFAD63D745D6F2DE5F17E5EAF0FC4963D261C8A12436518206DC093344D5AD293")>]
 [<assembly:System.Runtime.CompilerServices.InternalsVisibleTo("FSharp.Compiler.Hosted, PublicKey=002400000480000094000000060200000024000052534131000400000100010007D1FA57C4AED9F0A32E84AA0FAEFD0DE9E8FD6AEC8F87FB03766C834C99921EB23BE79AD9D5DCC1DD9AD236132102900B723CF980957FC4E177108FC607774F29E8320E92EA05ECE4E821C0A5EFE8F1645C4C0C93C1AB99285D622CAA652C1DFAD63D745D6F2DE5F17E5EAF0FC4963D261C8A12436518206DC093344D5AD293")>]
 
-do()
\ No newline at end of file
+do()
+
diff --git a/src/fsharp/FSharp.LanguageService.Compiler/FSharp.LanguageService.Compiler.fsproj b/src/fsharp/FSharp.LanguageService.Compiler/FSharp.LanguageService.Compiler.fsproj
index 3ef7013..d75bc50 100644
--- a/src/fsharp/FSharp.LanguageService.Compiler/FSharp.LanguageService.Compiler.fsproj
+++ b/src/fsharp/FSharp.LanguageService.Compiler/FSharp.LanguageService.Compiler.fsproj
@@ -56,6 +56,7 @@
       <OtherFlags>--internal --lexlib Internal.Utilities.Text.Lexing --parslib Internal.Utilities.Text.Parsing</OtherFlags>
       <Link>ilpars.fsy</Link>
     </FsYacc>
+    <Compile Include="InternalsVisibleTo.fs" />
     <Compile Include="..\ExtensibleDumper.fsi">
       <Link>ExtensibleDumper.fsi</Link>
     </Compile>
diff --git a/src/fsharp/FSharp.LanguageService.Compiler/InternalsVisibleTo.fs b/src/fsharp/FSharp.LanguageService.Compiler/InternalsVisibleTo.fs
new file mode 100644
index 0000000..29b8e38
--- /dev/null
+++ b/src/fsharp/FSharp.LanguageService.Compiler/InternalsVisibleTo.fs
@@ -0,0 +1,22 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+namespace Microsoft.FSharp
+open System.Reflection
+[<assembly:System.Runtime.CompilerServices.InternalsVisibleTo("Fsc, PublicKey=002400000480000094000000060200000024000052534131000400000100010007D1FA57C4AED9F0A32E84AA0FAEFD0DE9E8FD6AEC8F87FB03766C834C99921EB23BE79AD9D5DCC1DD9AD236132102900B723CF980957FC4E177108FC607774F29E8320E92EA05ECE4E821C0A5EFE8F1645C4C0C93C1AB99285D622CAA652C1DFAD63D745D6F2DE5F17E5EAF0FC4963D261C8A12436518206DC093344D5AD293")>]
+[<assembly:System.Runtime.CompilerServices.InternalsVisibleTo("FSharp.Build, PublicKey=002400000480000094000000060200000024000052534131000400000100010007D1FA57C4AED9F0A32E84AA0FAEFD0DE9E8FD6AEC8F87FB03766C834C99921EB23BE79AD9D5DCC1DD9AD236132102900B723CF980957FC4E177108FC607774F29E8320E92EA05ECE4E821C0A5EFE8F1645C4C0C93C1AB99285D622CAA652C1DFAD63D745D6F2DE5F17E5EAF0FC4963D261C8A12436518206DC093344D5AD293")>]
+[<assembly:System.Runtime.CompilerServices.InternalsVisibleTo("FSharp.QuickSearch, PublicKey=002400000480000094000000060200000024000052534131000400000100010007D1FA57C4AED9F0A32E84AA0FAEFD0DE9E8FD6AEC8F87FB03766C834C99921EB23BE79AD9D5DCC1DD9AD236132102900B723CF980957FC4E177108FC607774F29E8320E92EA05ECE4E821C0A5EFE8F1645C4C0C93C1AB99285D622CAA652C1DFAD63D745D6F2DE5F17E5EAF0FC4963D261C8A12436518206DC093344D5AD293")>]
+[<assembly:System.Runtime.CompilerServices.InternalsVisibleTo("FSharp.Compiler.Model, PublicKey=002400000480000094000000060200000024000052534131000400000100010007D1FA57C4AED9F0A32E84AA0FAEFD0DE9E8FD6AEC8F87FB03766C834C99921EB23BE79AD9D5DCC1DD9AD236132102900B723CF980957FC4E177108FC607774F29E8320E92EA05ECE4E821C0A5EFE8F1645C4C0C93C1AB99285D622CAA652C1DFAD63D745D6F2DE5F17E5EAF0FC4963D261C8A12436518206DC093344D5AD293")>]
+[<assembly:System.Runtime.CompilerServices.InternalsVisibleTo("Fsi, PublicKey=002400000480000094000000060200000024000052534131000400000100010007D1FA57C4AED9F0A32E84AA0FAEFD0DE9E8FD6AEC8F87FB03766C834C99921EB23BE79AD9D5DCC1DD9AD236132102900B723CF980957FC4E177108FC607774F29E8320E92EA05ECE4E821C0A5EFE8F1645C4C0C93C1AB99285D622CAA652C1DFAD63D745D6F2DE5F17E5EAF0FC4963D261C8A12436518206DC093344D5AD293")>]
+[<assembly:System.Runtime.CompilerServices.InternalsVisibleTo("FsiAnyCPU, PublicKey=002400000480000094000000060200000024000052534131000400000100010007D1FA57C4AED9F0A32E84AA0FAEFD0DE9E8FD6AEC8F87FB03766C834C99921EB23BE79AD9D5DCC1DD9AD236132102900B723CF980957FC4E177108FC607774F29E8320E92EA05ECE4E821C0A5EFE8F1645C4C0C93C1AB99285D622CAA652C1DFAD63D745D6F2DE5F17E5EAF0FC4963D261C8A12436518206DC093344D5AD293")>]
+[<assembly:System.Runtime.CompilerServices.InternalsVisibleTo("FSharp.LanguageService, PublicKey=002400000480000094000000060200000024000052534131000400000100010007D1FA57C4AED9F0A32E84AA0FAEFD0DE9E8FD6AEC8F87FB03766C834C99921EB23BE79AD9D5DCC1DD9AD236132102900B723CF980957FC4E177108FC607774F29E8320E92EA05ECE4E821C0A5EFE8F1645C4C0C93C1AB99285D622CAA652C1DFAD63D745D6F2DE5F17E5EAF0FC4963D261C8A12436518206DC093344D5AD293")>]
+[<assembly:System.Runtime.CompilerServices.InternalsVisibleTo("FSharp.LanguageService.Base, PublicKey=002400000480000094000000060200000024000052534131000400000100010007D1FA57C4AED9F0A32E84AA0FAEFD0DE9E8FD6AEC8F87FB03766C834C99921EB23BE79AD9D5DCC1DD9AD236132102900B723CF980957FC4E177108FC607774F29E8320E92EA05ECE4E821C0A5EFE8F1645C4C0C93C1AB99285D622CAA652C1DFAD63D745D6F2DE5F17E5EAF0FC4963D261C8A12436518206DC093344D5AD293")>]
+[<assembly:System.Runtime.CompilerServices.InternalsVisibleTo("FSharp.ProjectSystem.Base, PublicKey=002400000480000094000000060200000024000052534131000400000100010007D1FA57C4AED9F0A32E84AA0FAEFD0DE9E8FD6AEC8F87FB03766C834C99921EB23BE79AD9D5DCC1DD9AD236132102900B723CF980957FC4E177108FC607774F29E8320E92EA05ECE4E821C0A5EFE8F1645C4C0C93C1AB99285D622CAA652C1DFAD63D745D6F2DE5F17E5EAF0FC4963D261C8A12436518206DC093344D5AD293")>]
+[<assembly:System.Runtime.CompilerServices.InternalsVisibleTo("FSharp.ProjectSystem.FSharp, PublicKey=002400000480000094000000060200000024000052534131000400000100010007D1FA57C4AED9F0A32E84AA0FAEFD0DE9E8FD6AEC8F87FB03766C834C99921EB23BE79AD9D5DCC1DD9AD236132102900B723CF980957FC4E177108FC607774F29E8320E92EA05ECE4E821C0A5EFE8F1645C4C0C93C1AB99285D622CAA652C1DFAD63D745D6F2DE5F17E5EAF0FC4963D261C8A12436518206DC093344D5AD293")>]
+[<assembly:System.Runtime.CompilerServices.InternalsVisibleTo("FSharp.ProjectSystem.PropertyPages, PublicKey=002400000480000094000000060200000024000052534131000400000100010007D1FA57C4AED9F0A32E84AA0FAEFD0DE9E8FD6AEC8F87FB03766C834C99921EB23BE79AD9D5DCC1DD9AD236132102900B723CF980957FC4E177108FC607774F29E8320E92EA05ECE4E821C0A5EFE8F1645C4C0C93C1AB99285D622CAA652C1DFAD63D745D6F2DE5F17E5EAF0FC4963D261C8A12436518206DC093344D5AD293")>]
+[<assembly:System.Runtime.CompilerServices.InternalsVisibleTo("FSharp.Compiler.Interactive.Settings, PublicKey=002400000480000094000000060200000024000052534131000400000100010007D1FA57C4AED9F0A32E84AA0FAEFD0DE9E8FD6AEC8F87FB03766C834C99921EB23BE79AD9D5DCC1DD9AD236132102900B723CF980957FC4E177108FC607774F29E8320E92EA05ECE4E821C0A5EFE8F1645C4C0C93C1AB99285D622CAA652C1DFAD63D745D6F2DE5F17E5EAF0FC4963D261C8A12436518206DC093344D5AD293")>]
+[<assembly:System.Runtime.CompilerServices.InternalsVisibleTo("FSharp.Compiler.Server.Shared, PublicKey=002400000480000094000000060200000024000052534131000400000100010007D1FA57C4AED9F0A32E84AA0FAEFD0DE9E8FD6AEC8F87FB03766C834C99921EB23BE79AD9D5DCC1DD9AD236132102900B723CF980957FC4E177108FC607774F29E8320E92EA05ECE4E821C0A5EFE8F1645C4C0C93C1AB99285D622CAA652C1DFAD63D745D6F2DE5F17E5EAF0FC4963D261C8A12436518206DC093344D5AD293")>]
+[<assembly:System.Runtime.CompilerServices.InternalsVisibleTo("Salsa, PublicKey=002400000480000094000000060200000024000052534131000400000100010007D1FA57C4AED9F0A32E84AA0FAEFD0DE9E8FD6AEC8F87FB03766C834C99921EB23BE79AD9D5DCC1DD9AD236132102900B723CF980957FC4E177108FC607774F29E8320E92EA05ECE4E821C0A5EFE8F1645C4C0C93C1AB99285D622CAA652C1DFAD63D745D6F2DE5F17E5EAF0FC4963D261C8A12436518206DC093344D5AD293")>]
+[<assembly:System.Runtime.CompilerServices.InternalsVisibleTo("Unittests, PublicKey=002400000480000094000000060200000024000052534131000400000100010007D1FA57C4AED9F0A32E84AA0FAEFD0DE9E8FD6AEC8F87FB03766C834C99921EB23BE79AD9D5DCC1DD9AD236132102900B723CF980957FC4E177108FC607774F29E8320E92EA05ECE4E821C0A5EFE8F1645C4C0C93C1AB99285D622CAA652C1DFAD63D745D6F2DE5F17E5EAF0FC4963D261C8A12436518206DC093344D5AD293")>]
+
+do()
+
diff --git a/src/fsharp/Fsc/Fsc.fsproj b/src/fsharp/Fsc/Fsc.fsproj
index 03efe2c..8f5c42a 100644
--- a/src/fsharp/Fsc/Fsc.fsproj
+++ b/src/fsharp/Fsc/Fsc.fsproj
@@ -22,6 +22,7 @@
     <OtherFlags>$(OtherFlags) --warnon:1182</OtherFlags>
   </PropertyGroup>
   <ItemGroup>
+    <Compile Include="InternalsVisibleTo.fs" />
     <Compile Include="..\..\assemblyinfo\assemblyinfo.fsc.exe.fs">
       <Link>assemblyinfo.fsc.exe.fs</Link>
     </Compile>
diff --git a/src/fsharp/Fsc/InternalsVisibleTo.fs b/src/fsharp/Fsc/InternalsVisibleTo.fs
new file mode 100644
index 0000000..e1497d6
--- /dev/null
+++ b/src/fsharp/Fsc/InternalsVisibleTo.fs
@@ -0,0 +1,8 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+namespace Microsoft.FSharp
+open System.Reflection
+[<assembly:System.Runtime.CompilerServices.InternalsVisibleTo("Unittests, PublicKey=002400000480000094000000060200000024000052534131000400000100010007D1FA57C4AED9F0A32E84AA0FAEFD0DE9E8FD6AEC8F87FB03766C834C99921EB23BE79AD9D5DCC1DD9AD236132102900B723CF980957FC4E177108FC607774F29E8320E92EA05ECE4E821C0A5EFE8F1645C4C0C93C1AB99285D622CAA652C1DFAD63D745D6F2DE5F17E5EAF0FC4963D261C8A12436518206DC093344D5AD293")>]
+
+do()
+
diff --git a/tests/RunTests.cmd b/tests/RunTests.cmd
index 2d82b7c..4abecbb 100644
--- a/tests/RunTests.cmd
+++ b/tests/RunTests.cmd
@@ -36,12 +36,13 @@ set FSCBINPATH=%~dp0..\%FLAVOR%\net40\bin
 if /I "%2" == "fsharp" (goto :FSHARP)
 if /I "%2" == "fsharpqa" (goto :FSHARPQA)
 if /I "%2" == "coreunit" (goto :COREUNIT)
+if /I "%2" == "ideunit" (goto :IDEUNIT)
 
 :USAGE
 
 echo Usage:
 echo.
-echo RunTests.cmd ^<debug^|release^> ^<fsharp^|fsharpqa^|coreunit^> [TagToRun^|"Tags,To,Run"] [TagNotToRun^|"Tags,Not,To,Run"]
+echo RunTests.cmd ^<debug^|release^> ^<fsharp^|fsharpqa^|coreunit^|ideunit^> [TagToRun^|"Tags,To,Run"] [TagNotToRun^|"Tags,Not,To,Run"]
 echo.
 exit /b 1
 
@@ -147,4 +148,25 @@ if errorlevel 1 (
 echo nunit-console.exe /nologo /result=%XMLFILE% /output=%OUTPUTFILE% /err=%ERRORFILE% /work=%FILEDIR% %FSCBINPATH%\FSharp.Core.Unittests.dll 
      nunit-console.exe /nologo /result=%XMLFILE% /output=%OUTPUTFILE% /err=%ERRORFILE% /work=%FILEDIR% %FSCBINPATH%\FSharp.Core.Unittests.dll 
 
+goto :EOF
+
+:IDEUNIT
+
+set XMLFILE=IDEUnit_Xml.xml
+set OUTPUTFILE=IDEUnit_Output.log
+set ERRORFILE=IDEUnit_Error.log
+set FILEDIR=%~dp0
+
+where.exe nunit-console-x86.exe > NUL 2> NUL 
+if errorlevel 1 (
+  echo Error: nunit-console-x86.exe is not in the PATH
+  exit /b 1
+)
+
+for /f "tokens=*" %%a in  ('where.exe nunit-console-x86.exe')  do  (set nunitlocation=%%~dpa)
+xcopy /y "%nunitlocation%\lib\*.dll" "%FSCBINPATH%"
+
+echo nunit-console-x86.exe /nologo /result=%XMLFILE% /output=%OUTPUTFILE% /err=%ERRORFILE% /work=%FILEDIR% %FSCBINPATH%\Unittests.dll 
+     nunit-console-x86.exe /nologo /result=%XMLFILE% /output=%OUTPUTFILE% /err=%ERRORFILE% /work=%FILEDIR% %FSCBINPATH%\Unittests.dll 
+
 goto :EOF
\ No newline at end of file
diff --git a/tests/TESTGUIDE.html b/tests/TESTGUIDE.html
index 8dd3c2d..d54bf7d 100644
--- a/tests/TESTGUIDE.html
+++ b/tests/TESTGUIDE.html
@@ -319,6 +319,10 @@
 <p><b>Core Unit Test Suite</b>
 <p>The test cases for this suite reside next to the product code, at <code>src\fsharp\FSharp.Core.Unittests</code>.  This suite is a set of standard NUnit test cases, implemented in F#.  This suite focuses on validation of the core F# types and the public surface area of FSharp.Core.dll.
 
+<p><b>IDE Unit Test Suite</b>
+<p>The test cases for this suite reside next to the product code, at <code>vsintegration\src\unittests</code>.  This suite is a set of standard NUnit test cases, implemented in F#.  This suite exercises a wide range of behaviors in the F# Visual Studio project system and language service.
+
+
 <p><h3>Prerequisites</h3>
 <p>In order to run all of the tests, you will need to install
 <ul>
@@ -329,32 +333,31 @@
 
 <p>Before running tests, make sure you have successfully built all required projects, both product and test:
 <ul>
-<li>From the <code>src</code> directory</li>
-    <ul>
-        <li><code>msbuild fsharp-compiler-build.proj /p:TargetFramework=net40 /p:Configuration=<debug|release></code> to generate the compiler, libraries, and interative for .NET 4</li>
-        <li><code>msbuild fsharp-library-build.proj /p:TargetFramework=net20 /p:Configuration=<debug|release></code> to generate the libraries for .NET 2</li>
-        <li><code>msbuild fsharp-library-build.proj /p:TargetFramework=portable47 /p:Configuration=<debug|release></code> to generate the libraries for .NET portable profile 47</li>
-        <li><code>msbuild fsharp-typeproviders-build.proj /p:TargetFramework=net40 /p:Configuration=<debug|release></code> to generate FSharp.Data.TypeProviders.dll for .NET 4</li>
-        <li><code>update.cmd <debug|release> -ngen</code> to update the GAC, add strong name validation skips, and ngen latest-built binaries</li>
-    </ul>
-<li>From the <code>tests</code> directory</li>
-    <ul>
-        <li><code>BuildTestTools.cmd <debug|release></code> to build and binplace tools used during testing</li>
-    </ul>
+        <li><code>msbuild src\fsharp-compiler-build.proj /p:Configuration=<debug|release></code> to generate the compiler, libraries, and interative for .NET 4</li>
+        <li><code>msbuild src\fsharp-library-build.proj /p:TargetFramework=net20 /p:Configuration=<debug|release></code> to generate the libraries for .NET 2</li>
+        <li><code>msbuild src\fsharp-library-build.proj /p:TargetFramework=portable47 /p:Configuration=<debug|release></code> to generate the libraries for .NET portable profile 47</li>
+        <li><code>msbuild src\fsharp-library-build.proj /p:TargetFramework=portable7 /p:Configuration=<debug|release></code> to generate the libraries for .NET portable profile 7</li>
+        <li><code>msbuild src\fsharp-typeproviders-build.proj /p:Configuration=<debug|release></code> to generate FSharp.Data.TypeProviders.dll for .NET 4</li>
+        <li><code>msbuild src\fsharp-library-unittests-build.proj /p:Configuration=<debug|release></code> to generate FSharp.Core unit tests</li>
+        <li><code>msbuild vsintegration\fsharp-vsintegration-build.proj /p:Configuration=<debug|release></code> to generate all Visual Studio integration components</li>
+        <li><code>msbuild vsintegration\fsharp-vsintegration-unittests-build.proj /p:Configuration=<debug|release></code> to generate IDE unit tests</li>
+        <li><code>src\update.cmd <debug|release> -ngen</code> to update the GAC, add strong name validation skips, and ngen latest-built binaries</li>
+        <li><code>tests\BuildTestTools.cmd <debug|release></code> to build and binplace tools used during testing</li>
 </ul>
 
 <p><h3>Running Tests</h3>
 
-<p>The script <code>tests\RunTests.cmd</code> has been provided to make execution of the above 3 suites very simple.  You can kick off a full test run of any of the above suites like this:
+<p>The script <code>tests\RunTests.cmd</code> has been provided to make execution of the above suites very simple.  You can kick off a full test run of any of the above suites like this:
 <pre>
     RunTests.cmd <debug|release> fsharp [tags to run] [tags not to run]
     RunTests.cmd <debug|release> fsharpqa [tags to run] [tags not to run]
     RunTests.cmd <debug|release> coreunit
+    RunTests.cmd <debug|release> ideunit
 </pre>
 
 <p><code>RunTests.cmd</code> sets a handful of environment variables which allow for the tests to work, then puts together and executes the appropriate command line to start the specified test suite.
 
-<p>All test execution logs and result files will be dropped into the <code>tests</code> folder, and have file names matching <code>FSharp_*.*</code>, <code>FSharpQA_*.*</code>, or <code>CoreUnit_*.*</code>.
+<p>All test execution logs and result files will be dropped into the <code>tests</code> folder, and have file names matching <code>FSharp_*.*</code>, <code>FSharpQA_*.*</code>, <code>CoreUnit_*.*</code>, <code>IDEUnit_*.*</code>.
 
 <p>For the FSharp and FSharpQA suites, the list of test areas and their associated "tags" is stored at
 <pre>
@@ -388,6 +391,13 @@
 
 <p>You can execute and re-run these tests using any standard NUnit approach - via graphical <code>nunit.exe</code> or on the command line via <code>nunit-console.exe</code>.
 
+<p><b>IDE Unit Test Suite</b>
+
+<p>To build the unit test binary, call <code>msbuild fsharp-vsintegration-unittests-build.proj /p:TargetFramework=net40</code> from the <code>src</code> directory.  Tests are contained in the binary <code>Unittests.dll</code>. The IDE unit tests rely on the "Salsa" library, which is a set of Visual Studio mocks.  The code for Salsa resides at <code>vsintegration\src\Salsa</code>.  Note that for compatibility reasons, the IDE unit tests should be run in a 32-bit process, either <code>nuni [...]
+
+<p>You can execute and re-run these tests using any standard NUnit approach - via graphical <code>nunit-x86.exe</code> or on the command line via <code>nunit-console-x86.exe</code>.
+
+
 <h3>Other Tips</h3>
 <ul>
 <li>Run as admin, or a handful of tests will fail</li>
diff --git a/vsintegration/fsharp-vsintegration-build.proj b/vsintegration/fsharp-vsintegration-build.proj
new file mode 100644
index 0000000..9e49e26
--- /dev/null
+++ b/vsintegration/fsharp-vsintegration-build.proj
@@ -0,0 +1,13 @@
+<!-- Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information. -->
+<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
+  <PropertyGroup>
+    <TargetFramework Condition="'$(TargetFramework)'==''">net40</TargetFramework>
+  </PropertyGroup>
+
+  <ItemGroup>
+    <ProjectFiles Include="src\Deployment.sln"/>
+  </ItemGroup>
+
+  <Import Project="..\src\root.traversal.targets"/>
+</Project>
+
diff --git a/vsintegration/fsharp-vsintegration-unittests-build.proj b/vsintegration/fsharp-vsintegration-unittests-build.proj
new file mode 100644
index 0000000..d05b950
--- /dev/null
+++ b/vsintegration/fsharp-vsintegration-unittests-build.proj
@@ -0,0 +1,26 @@
+<!-- Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information. -->
+<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
+  <PropertyGroup>
+    <TargetFramework Condition="'$(TargetFramework)'==''">net40</TargetFramework>
+  </PropertyGroup>
+
+  <ItemGroup>
+    <ProjectFiles Include="src\salsa\Salsa.fsproj"/>
+    <ProjectFiles Include="src\unittests\unittests.fsproj"/>
+    <ProjectFiles Include="src\unittests\Resources.MockTypeProviders\DefinitionLocationAttribute\DefinitionLocationAttribute.csproj" />
+    <ProjectFiles Include="src\unittests\Resources.MockTypeProviders\DefinitionLocationAttributeFileDoesnotExist\DefinitionLocationAttributeFileDoesnotExist.csproj" />
+    <ProjectFiles Include="src\unittests\Resources.MockTypeProviders\DefinitionLocationAttributeLineDoesnotExist\DefinitionLocationAttributeLineDoesnotExist.csproj" />
+    <ProjectFiles Include="src\unittests\Resources.MockTypeProviders\DefinitionLocationAttributeWithSpaceInTheType\DefinitionLocationAttributeWithSpaceInTheType.csproj" />
+    <ProjectFiles Include="src\unittests\Resources.MockTypeProviders\DummyProviderForLanguageServiceTesting\DummyProviderForLanguageServiceTesting.fsproj" />
+    <ProjectFiles Include="src\unittests\Resources.MockTypeProviders\EditorHideMethodsAttribute\EditorHideMethodsAttribute.csproj" />
+    <ProjectFiles Include="src\unittests\Resources.MockTypeProviders\EmptyAssembly\EmptyAssembly.fsproj" />
+    <ProjectFiles Include="src\unittests\Resources.MockTypeProviders\XmlDocAttributeWithAdequateComment\XmlDocAttributeWithAdequateComment.csproj" />
+    <ProjectFiles Include="src\unittests\Resources.MockTypeProviders\XmlDocAttributeWithEmptyComment\XmlDocAttributeWithEmptyComment.csproj" />
+    <ProjectFiles Include="src\unittests\Resources.MockTypeProviders\XmlDocAttributeWithLocalizedComment\XmlDocAttributeWithLocalizedComment.csproj" />
+    <ProjectFiles Include="src\unittests\Resources.MockTypeProviders\XmlDocAttributeWithLongComment\XmlDocAttributeWithLongComment.csproj" />
+    <ProjectFiles Include="src\unittests\Resources.MockTypeProviders\XmlDocAttributeWithNullComment\XmlDocAttributeWithNullComment.csproj" />
+  </ItemGroup>
+
+  <Import Project="..\src\root.traversal.targets"/>
+</Project>
+
diff --git a/vsintegration/src/Salsa/InternalsVisibleTo.fs b/vsintegration/src/Salsa/InternalsVisibleTo.fs
new file mode 100644
index 0000000..466eb0c
--- /dev/null
+++ b/vsintegration/src/Salsa/InternalsVisibleTo.fs
@@ -0,0 +1,10 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+namespace Microsoft.FSharp
+open System.Reflection
+[<assembly:System.Runtime.CompilerServices.InternalsVisibleTo("Unittests, PublicKey=002400000480000094000000060200000024000052534131000400000100010007D1FA57C4AED9F0A32E84AA0FAEFD0DE9E8FD6AEC8F87FB03766C834C99921EB23BE79AD9D5DCC1DD9AD236132102900B723CF980957FC4E177108FC607774F29E8320E92EA05ECE4E821C0A5EFE8F1645C4C0C93C1AB99285D622CAA652C1DFAD63D745D6F2DE5F17E5EAF0FC4963D261C8A12436518206DC093344D5AD293")>]
+[<assembly:System.Runtime.CompilerServices.InternalsVisibleTo("SystematicUnitTests, PublicKey=002400000480000094000000060200000024000052534131000400000100010007D1FA57C4AED9F0A32E84AA0FAEFD0DE9E8FD6AEC8F87FB03766C834C99921EB23BE79AD9D5DCC1DD9AD236132102900B723CF980957FC4E177108FC607774F29E8320E92EA05ECE4E821C0A5EFE8F1645C4C0C93C1AB99285D622CAA652C1DFAD63D745D6F2DE5F17E5EAF0FC4963D261C8A12436518206DC093344D5AD293")>]
+
+
+do()
+
diff --git a/vsintegration/src/Salsa/Salsa.fsproj b/vsintegration/src/Salsa/Salsa.fsproj
new file mode 100644
index 0000000..5ede6d4
--- /dev/null
+++ b/vsintegration/src/Salsa/Salsa.fsproj
@@ -0,0 +1,107 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information. -->
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <FSharpSourcesRoot>..\..\..\src</FSharpSourcesRoot>
+    <vsFrameworkLatest>Microsoft.VisualStudio.Shell.12.0</vsFrameworkLatest>
+    <ProjectLanguage>FSharp</ProjectLanguage>
+    <SIGN_WITH_MSFT_KEY>true</SIGN_WITH_MSFT_KEY>
+  </PropertyGroup>
+  <Import Project="$(FSharpSourcesRoot)\FSharpSource.settings.targets" />
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{fbd4b354-dc6e-4032-8ec7-c81d8dfb1af7}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AssemblyName>Salsa</AssemblyName>
+    <NoWarn>$(NoWarn);45;47;52;58;75</NoWarn>
+    <DefineConstants>FX_ATLEAST_45;$(DefineConstants)</DefineConstants>
+  </PropertyGroup>
+  <ItemGroup>
+    <Compile Include="$(FSharpSourcesRoot)\utils\CompilerLocationUtils.fs" />
+    <Compile Include="..\unittests\TestLib.Utils.fs">
+      <Link>UnitTests.TestLib.Utils.fs</Link>
+    </Compile>
+    <Compile Include="InternalsVisibleTo.fs" />
+    <Compile Include="VsMocks.fs" />
+    <Compile Include="Salsa.fsi" />
+    <Compile Include="Salsa.fs" />
+    <Compile Include="SalsaUtils.fsi" />
+    <Compile Include="SalsaUtils.fs" />
+  </ItemGroup>
+  <ItemGroup>
+    <Reference Include="mscorlib" />
+    <Reference Include="System" />
+    <Reference Include="System.ComponentModel.Composition" />
+    <Reference Include="System.Xml" />
+    <Reference Include="System.Windows.Forms" />
+    <Reference Include="Microsoft.Build, Version=12.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+      <SpecificVersion>true</SpecificVersion>
+    </Reference>
+    <Reference Include="Microsoft.Build.Engine, Version=12.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+      <SpecificVersion>true</SpecificVersion>
+    </Reference>
+    <Reference Include="Microsoft.Build.Framework, Version=12.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+      <SpecificVersion>true</SpecificVersion>
+    </Reference>
+    <Reference Include="Microsoft.Build.Utilities.v12.0" />
+    <Reference Include="EnvDTE.dll" />
+    <Reference Include="EnvDTE80.dll" />
+    <Reference Include="VSLangProj" />
+    <Reference Include="VSLangProj80" />
+    <Reference Include="Microsoft.VisualStudio.OLE.Interop.dll" />
+    <Reference Include="$(vsFrameworkLatest)" />
+    <Reference Include="Microsoft.VisualStudio.Threading" />
+    <Reference Include="Microsoft.VisualStudio.Shell.Interop.8.0.dll" />
+    <Reference Include="Microsoft.VisualStudio.Shell.Interop.9.0.dll" />
+    <Reference Include="Microsoft.VisualStudio.Shell.Interop.10.0.dll" />
+    <Reference Include="Microsoft.VisualStudio.Shell.Interop.11.0.dll" />
+    <Reference Include="Microsoft.VisualStudio.Shell.Interop.dll" />
+    <Reference Include="Microsoft.VisualStudio.Shell.Design" />
+    <Reference Include="Microsoft.VisualStudio.ProjectAggregator" />
+    <Reference Include="Microsoft.VisualStudio.TextManager.Interop.dll" />
+    <Reference Include="Microsoft.VisualStudio.TextManager.Interop.8.0.dll" />
+    <Reference Include="Microsoft.VisualStudio.Designer.Interfaces" />
+    <Reference Include="Microsoft.VisualStudio.CommonIDE" />
+    <Reference Include="Microsoft.VisualStudio.VSHelp.dll" />
+    <Reference Include="Microsoft.VisualStudio.Text.Data" />
+    <Reference Include="Microsoft.VisualStudio.CoreUtility" />
+    <Reference Include="nunit.framework" />
+    <ProjectReference Include="$(FSharpSourcesRoot)\fsharp\FSharp.Core\FSharp.Core.fsproj">
+      <Project>{DED3BBD7-53F4-428A-8C9F-27968E768605}</Project>
+      <Name>FSharp.Core</Name>
+    </ProjectReference>
+    <ProjectReference Include="$(FSharpSourcesRoot)\fsharp\FSharp.Build\FSharp.Build.fsproj">
+      <Name>FSharp.Build</Name>
+      <Project>{702a7979-bcf9-4c41-853e-3adfc9897890}</Project>
+      <Private>True</Private>
+    </ProjectReference>
+    <ProjectReference Include="$(FSharpSourcesRoot)\fsharp\FSharp.LanguageService.Compiler\FSharp.LanguageService.Compiler.fsproj">
+      <Name>FSharp.LanguageService.Compiler</Name>
+      <Project>{a437a6ec-5323-47c2-8f86-e2cac54ff152}</Project>
+      <Private>True</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\vs\FsPkgs\FSharp.LanguageService\FSharp.LanguageService.Base\FSharp.LanguageService.Base.csproj">
+      <Name>FSharp.LanguageService.Base</Name>
+      <Project>{1c5c163c-37ea-4a3c-8ccc-0d34b74bf8ef}</Project>
+      <Private>True</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\vs\FsPkgs\FSharp.LanguageService\FSharp.LanguageService.fsproj">
+      <Name>FSharp.LanguageService</Name>
+      <Project>{ee85aab7-cda0-4c4e-bda0-a64ccc413e3f}</Project>
+      <Private>True</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\vs\FsPkgs\FSharp.Project\Common.Source.CSharp\Project\ProjectSystem.Base.csproj">
+      <Name>ProjectSystem.Base</Name>
+      <Project>{b700e38b-f8c0-4e49-b5ec-db7b7ac0c4e7}</Project>
+      <Private>True</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\vs\FsPkgs\FSharp.Project\FS\ProjectSystem.fsproj">
+      <Name>FSharp.ProjectSystem.FSharp</Name>
+      <Project>{6196B0F8-CAEA-4CF1-AF82-1B520F77FE44}</Project>
+      <Private>True</Private>
+    </ProjectReference>
+  </ItemGroup>
+  <Import Project="$(FSharpSourcesRoot)\FSharpSource.targets" />
+</Project>
diff --git a/vsintegration/src/Salsa/SalsaUtils.fs b/vsintegration/src/Salsa/SalsaUtils.fs
new file mode 100644
index 0000000..c2261ec
--- /dev/null
+++ b/vsintegration/src/Salsa/SalsaUtils.fs
@@ -0,0 +1,347 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+namespace Salsa
+
+open System
+open System.IO
+open Microsoft.VisualStudio.FSharp.ProjectSystem
+open Microsoft.VisualStudio.FSharp.LanguageService
+open Microsoft.VisualStudio.TextManager.Interop
+open Microsoft.FSharp.Compiler.SourceCodeServices
+open NUnit.Framework
+
+open Salsa.Salsa
+
+/// Utilities related to VsOps
+module internal VsOpsUtils =
+
+    // ------------------------------------------------------------------------
+    let opsOfProj (p : OpenProject) = p.VS.VsOps
+    let opsOfFile (f : OpenFile) = f.VS.VsOps
+    let DefaultBuildActionOfFilename(filename) = 
+        match Path.GetExtension(filename) with 
+        | ".fsx" -> BuildAction.None
+        | ".resx"
+        | ".resources" -> BuildAction.EmbeddedResource
+        | _ -> BuildAction.Compile
+        
+    let CreateSolution(vs : VisualStudio) = vs.VsOps.CreateSolution(vs)
+    let ClearLanguageServiceRootCachesAndCollectAndFinalizeAllTransients(vs : VisualStudio) = vs.VsOps.ClearLanguageServiceRootCachesAndCollectAndFinalizeAllTransients(vs)
+    let GetOutputWindowPaneLines(vs : VisualStudio) = vs.VsOps.GetOutputWindowPaneLines(vs)
+    let CloseSolution(soln : OpenSolution)             = soln.VS.VsOps.CloseSolution(soln)
+
+    let AddTypeProviderApprovedForDevelopment(assemblyFileName) = 
+        Microsoft.FSharp.Compiler.ExtensionTyping.ApprovalIO.ReplaceApprovalStatus 
+            None 
+            (Microsoft.FSharp.Compiler.ExtensionTyping.ApprovalIO.TypeProviderApprovalStatus.Trusted(Microsoft.FSharp.Compiler.ExtensionTyping.ApprovalIO.partiallyCanonicalizeFileName assemblyFileName))
+    let ClearAllTypeProviderApprovals() = 
+        if System.IO.File.Exists(Microsoft.FSharp.Compiler.ExtensionTyping.ApprovalIO.ApprovalsAbsoluteFileName) then
+            System.IO.File.Delete(Microsoft.FSharp.Compiler.ExtensionTyping.ApprovalIO.ApprovalsAbsoluteFileName)
+
+    let CreateProject(solution : OpenSolution, projectname) = 
+        solution.VS.VsOps.CreateProject(solution,projectname)
+    let NewFile(vs : VisualStudio, filename,lines) = 
+        vs.VsOps.NewFile(vs,filename,DefaultBuildActionOfFilename filename,lines)
+    let DeleteFileFromDisk(vs : VisualStudio, file) = 
+        vs.VsOps.DeleteFileFromDisk(file)
+    let AddFileFromText(project, filename, lines) = 
+        (opsOfProj project).AddFileFromText(project,filename,filename,DefaultBuildActionOfFilename filename,lines)
+    let AddFileFromTextBlob(project : OpenProject, filename, lines : string)  = 
+        (opsOfProj project).AddFileFromText(project,filename,filename,DefaultBuildActionOfFilename filename, Array.toList (lines.Split( [| "\r\n" |], StringSplitOptions.None)))
+    let AddFileFromTextEx(project : OpenProject,filenameOnDisk,filenameInProject,buildAction,lines)  = 
+        (opsOfProj project).AddFileFromText(project,filenameOnDisk,filenameInProject,buildAction,lines)
+    let AddLinkedFileFromTextEx(project : OpenProject,filenameOnDisk,includeFilenameInProject,linkFilenameInProject,lines) = 
+        (opsOfProj project).AddLinkedFileFromText(project,filenameOnDisk,includeFilenameInProject,linkFilenameInProject,DefaultBuildActionOfFilename filenameOnDisk,lines)
+    let AddAssemblyReference(project : OpenProject,reference) = 
+        (opsOfProj project).AddAssemblyReference(project,reference,false)
+    let AddAssemblyReferenceEx(project : OpenProject,reference,specificVersion) = 
+        (opsOfProj project).AddAssemblyReference(project,reference,specificVersion)
+    let AddProjectReference(project1,project2) = 
+        (opsOfProj project1).AddProjectReference(project1,project2)
+    let PlaceIntoProjectFileBeforeImport(project,xml)   = 
+        (opsOfProj project).PlaceIntoProjectFileBeforeImport(project,xml)
+    let ProjectDirectory(project) = 
+        (opsOfProj project).ProjectDirectory(project)
+    let ProjectFile(project) = 
+        (opsOfProj project).ProjectFile(project)
+    let SetVersionFile(project,file)    = 
+        (opsOfProj project).SetVersionFile(project,file)
+    let SetConfigurationAndPlatform(project,configAndPlatform) = 
+        (opsOfProj project).SetConfigurationAndPlatform(project,configAndPlatform)
+    let SetOtherFlags(project,flags)    = 
+        (opsOfProj project).SetOtherFlags(project,flags)
+    let GetErrors(project) = 
+        (opsOfProj project).GetErrors(project)
+    let SetProjectDefines(project,defines) = 
+        (opsOfProj project).SetProjectDefines(project,defines)
+    let AddDisabledWarning(project,code) = 
+        (opsOfProj project).AddDisabledWarning(project,code)
+    let Build(project) = 
+        (opsOfProj project).BuildProject(project,null)
+    let BuildTarget(project,target) = 
+        (opsOfProj project).BuildProject(project,target)
+    let GetMainOutputAssembly(project)  = 
+        (opsOfProj project).GetMainOutputAssembly(project)
+    let Save(project) = 
+        (opsOfProj project).SaveProject(project)
+    let OpenFileViaOpenFile(vs : VisualStudio, filename) = 
+        vs.VsOps.OpenFileViaOpenFile(vs,filename)
+    let OpenFile(project,filename) = 
+        (opsOfProj project).OpenFile(project,filename)
+    let GetOpenFiles(project) = 
+        (opsOfProj project).GetOpenFiles(project)
+    let OpenExistingProject(vs :VisualStudio, dir,projname) = 
+        vs.VsOps.OpenExistingProject(vs,dir,projname)
+    let MoveCursorTo(file,line,col) = 
+        (opsOfFile file).MoveCursorTo(file,line,col)
+    let GetCursorLocation(file) = 
+        (opsOfFile file).GetCursorLocation(file)
+    let MoveCursorToEndOfMarker(file,marker) = 
+        (opsOfFile file).MoveCursorToEndOfMarker(file, marker)
+    let GetMatchingBracesForPositionAtCursor(file) = 
+        (opsOfFile file).GetMatchingBracesForPositionAtCursor(file)
+    let MoveCursorToStartOfMarker(file,marker) = 
+        (opsOfFile file).MoveCursorToStartOfMarker(file,marker)
+    let GetQuickInfoAtCursor(file) = 
+        (opsOfFile file).GetQuickInfoAtCursor(file)
+    let GetQuickInfoAndSpanAtCursor(file) = 
+        (opsOfFile file).GetQuickInfoAndSpanAtCursor(file)
+    let GetNameOfOpenFile(file) = 
+        (opsOfFile file).GetNameOfOpenFile(file)
+    let GetCheckOptionsOfScript(file) = 
+        (opsOfFile file).GetCheckOptionsOfScript(file)
+    let GetParameterInfoAtCursor(file) = 
+        (opsOfFile file).GetParameterInfoAtCursor(file)
+    let GetParameterInfoAtCursorNoFallback(file) = 
+        (opsOfFile file).GetParameterInfoAtCursorNoFallback(file)
+    let GetTokenTypeAtCursor(file) = 
+        (opsOfFile file).GetTokenTypeAtCursor(file)
+    let GetSquiggleAtCursor(file) = 
+        (opsOfFile file).GetSquiggleAtCursor(file)
+    let GetSquigglesAtCursor(file) = 
+        (opsOfFile file).GetSquigglesAtCursor(file)
+    let AutoCompleteAtCursor(file) = 
+        (opsOfFile file).AutoCompleteAtCursor(file)
+    let CtrlSpaceCompleteAtCursor(file) = 
+        (opsOfFile file).CompleteAtCursorForReason(file,Microsoft.VisualStudio.FSharp.LanguageService.BackgroundRequestReason.CompleteWord)
+    let CompleteAtCursorForReason(file,reason) = 
+        (opsOfFile file).CompleteAtCursorForReason(file,reason)
+    let CompletionBestMatchAtCursorFor(file, value, filterText) = 
+        (opsOfFile file).CompletionBestMatchAtCursorFor(file, value, filterText)
+    let GotoDefinitionAtCursor file  = 
+        (opsOfFile file).GotoDefinitionAtCursor file false
+    let GotoDefinitionAtCursorForceGeneration file = 
+        (opsOfFile file).GotoDefinitionAtCursor file true
+    let GetNavigationContentAtCursor(file) = 
+        (opsOfFile file).GetNavigationContentAtCursor(file)
+    let GetHiddenRegionCommands(file) = 
+        (opsOfFile file).GetHiddenRegionCommands(file)
+    let GetIdentifierAtCursor file = 
+        (opsOfFile file).GetIdentifierAtCursor file
+    let GetF1KeywordAtCursor file = 
+        (opsOfFile file).GetF1KeywordAtCursor file
+    let GetLineNumber file n = 
+        (opsOfFile file).GetLineNumber file n
+    let GetAllLines file= 
+        (opsOfFile file).GetAllLines file
+    let SwitchToFile (vs : VisualStudio) file = 
+        vs.VsOps.SwitchToFile(vs,file)
+    let OnIdle(vs : VisualStudio) = vs.VsOps.OnIdle(vs)
+    let ShiftKeyDown(vs : VisualStudio) = vs.VsOps.ShiftKeyDown(vs)
+    let ShiftKeyUp(vs : VisualStudio) = vs.VsOps.ShiftKeyUp(vs) 
+    let TakeCoffeeBreak(vs : VisualStudio) = vs.VsOps.TakeCoffeeBreak(vs)
+    let ReplaceFileInMemory(file :OpenFile) lines = (opsOfFile file).ReplaceFileInMemory(file,lines,true)
+    let ReplaceFileInMemoryWithoutCoffeeBreak(file :OpenFile) lines   = (opsOfFile file).ReplaceFileInMemory(file,lines,false)
+    let SaveFileToDisk(file :OpenFile)  = (opsOfFile file).SaveFileToDisk(file)
+    let AutoCompleteMemberDataTipsThrowsScope(vs : VisualStudio, message)  = vs.VsOps.AutoCompleteMemberDataTipsThrowsScope(message)
+    let Cleanup(vs : VisualStudio) = vs.VsOps.CleanUp(vs) 
+
+    let OutOfConeFilesAreAddedAsLinks(vs : VisualStudio) = vs.VsOps.OutOfConeFilesAreAddedAsLinks
+    let SupportsOutputWindowPane(vs : VisualStudio) = vs.VsOps.SupportsOutputWindowPane
+
+
+    // ------------------------------------------------------------------------
+
+    type SetMarkerPoint =
+        | StartOfMarker
+        | EndOfMarker
+
+    /// Creates a single file project/solution
+    let CreateSingleFileProject (vs, fileContents) =
+        let solution = CreateSolution(vs)
+        let project = CreateProject(solution, "testproject")
+        let _ = AddFileFromTextBlob(project, "File1.fs", fileContents)
+        let file = OpenFile(project, "File1.fs")
+        (solution, project, file)
+
+    /// Creates a single file project/solution where the lone file is named.
+    let CreateNamedSingleFileProject (vs, (fileContents, fileName)) =
+        let solution = CreateSolution(vs)
+        let project = CreateProject(solution, "testproject")
+        let _ = AddFileFromTextBlob(project, fileName, fileContents)
+        let file = OpenFile(project, fileName)
+        (solution, project, file)
+
+    // ------------------------------------------------------------------------
+
+    /// Verify that items obtained from the navigation bar contain the specified item
+    let AssertRegionListContains(expected:list<(int*int)*(int*int)>, regions:list<NewHiddenRegion>) =
+      for (sl,sc), (el,ec) in expected do 
+        match regions |> List.tryFind (fun reg -> 
+            let span = reg.tsHiddenText
+            (span.iStartIndex = sc) && (span.iEndIndex = ec) && 
+              (span.iStartLine = sl) && (span.iEndLine = el) ) with
+        | None -> 
+            printfn "Regions found: %A" (regions |> List.map (fun itm -> 
+              ((itm.tsHiddenText.iStartIndex, itm.tsHiddenText.iStartLine),
+               (itm.tsHiddenText.iEndIndex, itm.tsHiddenText.iEndLine)) ))
+            Assert.Fail(sprintf "Couldn't find region (%d, %d) - (%d, %d)" sl sc el ec)
+        | _ -> ()
+      
+    /// Verify that items obtained from the navigation bar contain the specified item
+    let AssertNavigationContains (items:DropDownMember[], expected) =
+      match items |> Array.tryFind (fun itm -> itm.Label = expected) with
+      | None -> 
+          printfn "Navigation bar items: %A" (items |> Array.map (fun itm -> itm.Label))
+          Assert.Fail(sprintf "Couldn't find '%s' in drop down bar." expected)
+      | _ -> ()
+
+    /// Verify that items obtained from the navigation bar contain all specified item
+    let AssertNavigationContainsAll (items:DropDownMember[], allExpected) =
+      for expected in allExpected do
+        match items |> Array.tryFind (fun itm -> itm.Label = expected) with
+        | None -> 
+            printfn "Navigation bar items: %A" (items |> Array.map (fun itm -> itm.Label))
+            Assert.Fail(sprintf "Couldn't find '%s' in drop down bar." expected)
+        | _ -> ()
+    
+    // ------------------------------------------------------------------------
+    
+    /// Verify the completion list is empty, typically for negative tests
+    let AssertCompListIsEmpty (completions : CompletionItem[]) = 
+      if not (Array.isEmpty completions) then
+          printfn "Expected empty completion list but got: %A" (completions |> Array.map (fun (nm, _, _, _) -> nm))
+      Assert.IsTrue(Array.isEmpty completions, "Expected empty completion list but got some items")
+
+    /// Verify that the given completion list contains a member with the given name
+    let AssertCompListContains(completions : CompletionItem[], membername) =
+        let found = completions |> Array.filter(fun (name,_,_,_) -> name = membername) |> Array.length
+        if found = 0 then
+            printfn "Failed to find expected value %s in " membername
+            let MAX = 25
+            printfn "Completion list = %s" (if completions.Length > MAX then sprintf "%A ... and more" completions.[0..MAX] else sprintf "%A" completions)
+            Assert.Fail(sprintf "Couldn't find '%s' in completion list" membername)
+
+    /// Verify the completion list does not contain a member with the given name
+    let AssertCompListDoesNotContain(completions : CompletionItem[], membername) =
+        let found = completions |> Array.filter(fun (name,_,_,_) -> name = membername) |> Array.length
+        if found <> 0 then
+            printfn "Value %s should have been absent from " membername
+            printfn "Completion list = %A" completions
+            Assert.Fail(sprintf "Found unexpected '%s' in completion list" membername)
+                         
+    // Verify the completion list contains every member in the list
+    let rec AssertCompListContainsAll(completions : CompletionItem[], expectedCompletions) =
+        match expectedCompletions with
+        | [] -> ()
+        | h :: t ->
+            AssertCompListContains(completions, h)
+            AssertCompListContainsAll(completions, t)
+            ()
+
+    // Verify the completion list contains every member in the list
+    let rec AssertCompListContainsExactly(completions : CompletionItem[], expectedCompletions) =
+        AssertCompListContainsAll(completions, expectedCompletions)
+        if (completions.Length <> (expectedCompletions |> List.length)) then
+            printfn "Completion list contained all the expected completions, but there were additional unexpected completions."
+            printfn "Expected = %A" expectedCompletions
+            printfn "Actual = %A" completions
+            Assert.Fail("Extra completions found in list")
+
+    /// Verify the completion list does not contain any member in the list
+    let rec AssertCompListDoesNotContainAny(completions : CompletionItem[], itemsNotInCompList) =
+        match itemsNotInCompList with
+        | [] -> ()
+        | h :: t ->
+            AssertCompListDoesNotContain(completions, h)
+            AssertCompListDoesNotContainAny(completions, t)
+            ()
+
+    /// Simulates pressing '.' at the mark and returns the completion list
+    let DotCompletionAtMarker markerDirection (file : OpenFile) marker =
+        
+        // Simulate pressing '.'
+        let orgFileContents = GetAllLines file
+        
+        // Check that the marker is unique, otherwise we can't determine where to put the '.'
+        let markerLines = orgFileContents |> Seq.filter (fun line -> line.Contains(marker)) |> Seq.length 
+        if markerLines = 0 then Assert.Fail("Unable to find marker in source code.")
+        if markerLines > 1 then Assert.Fail <| sprintf "Found marker [%s] multiple times in source file." marker
+        
+        // Replace marker with "<marker>."
+        let replaceMarker =
+            match markerDirection with 
+            | StartOfMarker -> (fun (line : string) -> line.Replace(marker, "." + marker))
+            | EndOfMarker   -> (fun (line : string) -> line.Replace(marker, marker + "."))
+        
+        let newFileContents = orgFileContents |> List.map replaceMarker
+        
+        // Now apply our change & get the comp list
+        ReplaceFileInMemory file newFileContents
+        
+        match markerDirection with 
+        | StartOfMarker -> MoveCursorToStartOfMarker(file, marker)
+        | EndOfMarker   -> MoveCursorToEndOfMarker(file, marker + ".")
+
+        let compList = AutoCompleteAtCursor(file)
+       
+        // Now restore the origional file contents
+        ReplaceFileInMemory file orgFileContents
+        
+        compList
+        
+    /// Gets the completion list as if you pressed '.' at the START of the marker.
+    let DotCompletionAtStartOfMarker : (OpenFile -> string -> CompletionItem[]) = DotCompletionAtMarker StartOfMarker
+
+    /// Gets the completion list as if you pressed '.' at the END of the marker.
+    let DotCompletionAtEndOfMarker   : (OpenFile -> string -> CompletionItem[]) = DotCompletionAtMarker EndOfMarker
+
+    // ------------------------------------------------------------------------
+ 
+    /// Abbreviation for 'None', to indiciate a GotoDefn failure
+    let GotoDefnFailure       = None : (string * string) option
+    /// Abbreviation for 'Some(ident, lineOfCode)'
+    let GotoDefnSuccess x y = Some (x, y) : (string * string) option
+    
+    /// Checks that a goto definition result matches the expected value.
+    /// Expected = Some(identifierAtCursor, lineOfCodeAtCursor)
+    let CheckGotoDefnResult (expected : (string * string) option) (file : OpenFile) (actual : GotoDefnResult) : unit =
+        match (expected, actual.ToOption()) with
+        // Success cases
+        // GotoDefn retrieved a result and we expected to find something
+        | (Some (toFind, expLine), Some (span, actFile)) 
+            ->  match GetIdentifierAtCursor file with
+                | None         ->   Assert.Fail ("No identifier at cursor. This indicates a bug in GotoDefinition.")
+                | Some (id, _) ->   // Are we on the identifier we expect?
+                                    Assert.AreEqual (toFind, id)
+                                    // Do the lines of code match what we expect?
+                                    // - Eliminate white space to eliminate trivial errors
+                                    // - +1 to adjust for 1-index line numbers
+                                    Assert.AreEqual (
+                                        expLine.Trim(), 
+                                        (span.iStartLine |> (+) 1 |> GetLineNumber (OpenFileViaOpenFile(file.VS, actFile))).Trim ()
+                                    ) 
+                                    // Looks like it's legit!
+                                    ()
+        // We expected Goto Definition to fail and it did. 
+        // (Such as Goto Definition on keyword or symbol.)
+        | (None, None) 
+            -> ()
+        
+        // Error cases
+        | (Some (x,_), None)     
+            -> Assert.Fail <| sprintf "Expected to find the definition of '%s' but GotoDefn failed." x
+
+        | (None, Some (_,file)) 
+            -> Assert.Fail <| sprintf "Expected GotoDefn to fail, but it went to a definition in file %s" file
+
diff --git a/vsintegration/src/Salsa/SalsaUtils.fsi b/vsintegration/src/Salsa/SalsaUtils.fsi
new file mode 100644
index 0000000..1f049ae
--- /dev/null
+++ b/vsintegration/src/Salsa/SalsaUtils.fsi
@@ -0,0 +1,143 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+namespace Salsa
+
+open Microsoft.VisualStudio
+open Microsoft.VisualStudio.Shell.Interop
+open Microsoft.VisualStudio.FSharp.ProjectSystem
+open Microsoft.VisualStudio.FSharp.LanguageService
+open Microsoft.VisualStudio.TextManager.Interop
+open Microsoft.FSharp.Compiler.SourceCodeServices
+open Microsoft.Build.Framework
+
+open Salsa
+
+
+/// Functions for validating tests using VsOps. (Calls Assert behind the scenes.)
+module internal VsOpsUtils =
+
+    // ------------------------------------------------------------------------
+    
+    // Wrappers on top of VSOps functions, these make it easier to interact with
+    // VSOps as well as enabling us to change VsOps slightly without breaking the world
+
+    val CreateSolution                    : VisualStudio -> OpenSolution
+    val GetOutputWindowPaneLines          : VisualStudio -> string list
+    val CloseSolution                     : OpenSolution -> unit
+
+    /// pass absolute filename
+    val AddTypeProviderApprovedForDevelopment : string -> unit
+    val ClearAllTypeProviderApprovals : unit -> unit
+
+    val CreateProject                     : OpenSolution * string -> OpenProject
+    /// Add a new file not in any particulare project.
+    val NewFile                           : VisualStudio * string * string list -> File
+    val DeleteFileFromDisk : VisualStudio * File -> unit
+    val AddFileFromText                   : OpenProject * string * string list -> File
+    val AddFileFromTextBlob               : OpenProject * string * string -> File
+    val AddFileFromTextEx                 : OpenProject * string * string * Salsa.Salsa.BuildAction * string list -> File
+    val AddLinkedFileFromTextEx           : OpenProject * string * string * string * string list -> File
+    val AddAssemblyReference              : OpenProject * string -> unit 
+    val AddAssemblyReferenceEx              : OpenProject * string * bool -> unit 
+    val AddProjectReference               : OpenProject * OpenProject -> unit 
+    val ProjectDirectory                  : OpenProject -> string
+    val ProjectFile                       : OpenProject -> string
+    val SetVersionFile                    : OpenProject * string -> unit
+    val SetOtherFlags                     : OpenProject * string -> unit
+    val SetConfigurationAndPlatform       : OpenProject * string -> unit
+    val AddDisabledWarning                : OpenProject * string -> unit
+    val Build                             : OpenProject -> BuildResult
+    val BuildTarget                       : OpenProject * string -> BuildResult
+    val GetMainOutputAssembly             : OpenProject -> string
+    val Save                              : OpenProject -> unit
+    val GetErrors                         : OpenProject -> Error list 
+    /// Open a file outside of any project as if from File\Open\File... menu item. 
+    val OpenFileViaOpenFile               : VisualStudio * string -> OpenFile
+    val OpenFile                          : OpenProject * string -> OpenFile 
+    val GetOpenFiles                      : OpenProject -> OpenFile list
+    val SetProjectDefines                 : OpenProject * string list -> unit
+    val PlaceIntoProjectFileBeforeImport  : OpenProject * string -> unit
+    val OpenExistingProject               : VisualStudio * string * string -> OpenProject * OpenSolution
+    val MoveCursorTo                      : OpenFile * int * int -> unit
+    val GetCursorLocation                 : OpenFile -> int * int
+    val GetLineNumber                     : OpenFile -> int -> string
+    val GetAllLines                       : OpenFile -> string list
+    val SwitchToFile                      : VisualStudio -> OpenFile -> unit
+    val OnIdle                            : VisualStudio -> unit
+    val ShiftKeyDown                      : VisualStudio -> unit
+    val ShiftKeyUp                        : VisualStudio -> unit
+    val ClearLanguageServiceRootCachesAndCollectAndFinalizeAllTransients : VisualStudio -> unit
+    val TakeCoffeeBreak                   : VisualStudio -> unit 
+    val ReplaceFileInMemory               : OpenFile -> string list -> unit
+    val ReplaceFileInMemoryWithoutCoffeeBreak   : OpenFile -> string list -> unit
+    val SaveFileToDisk                    : OpenFile -> unit
+    val GetSquiggleAtCursor               : OpenFile -> (Microsoft.VisualStudio.FSharp.LanguageService.Severity * string) option
+    val GetSquigglesAtCursor               : OpenFile -> (Microsoft.VisualStudio.FSharp.LanguageService.Severity * string) list
+    /// does a BackgroundRequestReason.MemberSelect at the cursor
+    val AutoCompleteAtCursor              : OpenFile -> CompletionItem array
+    /// does a BackgroundRequestReason.CompleteWord at the cursor
+    val CtrlSpaceCompleteAtCursor         : OpenFile -> CompletionItem array
+    /// like AutoCompleteAtCursor, but can pass e.g. BackgroundRequestReason.CompleteWord to do Ctrl-space rather than auto-dot-popup-completion
+    val CompleteAtCursorForReason         : OpenFile * Microsoft.VisualStudio.FSharp.LanguageService.BackgroundRequestReason -> CompletionItem array
+    val CompletionBestMatchAtCursorFor    : OpenFile * string * string option -> (string * bool * bool) option 
+    val MoveCursorToEndOfMarker           : OpenFile * string -> unit
+    val MoveCursorToStartOfMarker         : OpenFile * string -> unit
+    val GetQuickInfoAtCursor              : OpenFile -> string   
+    val GetQuickInfoAndSpanAtCursor       : OpenFile -> string*TextSpan
+    val GetNameOfOpenFile                 : OpenFile -> string
+    val GetCheckOptionsOfScript           : OpenFile -> CheckOptions
+    val GetParameterInfoAtCursor          : OpenFile -> MethodListForAMethodTip
+    val GetParameterInfoAtCursorNoFallback: OpenFile -> MethodListForAMethodTip
+    val GetTokenTypeAtCursor              : OpenFile -> Salsa.Salsa.TokenType
+    val GetIdentifierAtCursor             : OpenFile -> (string * int) option
+    val GetF1KeywordAtCursor              : OpenFile -> string option
+    val GotoDefinitionAtCursor            : OpenFile -> GotoDefnResult
+    val GotoDefinitionAtCursorForceGeneration : OpenFile -> GotoDefnResult
+    val GetNavigationContentAtCursor      : OpenFile -> NavigationBarResult
+    val GetHiddenRegionCommands           : OpenFile -> list<NewHiddenRegion> * Map<uint32, TextSpan>
+    val Cleanup                           : VisualStudio -> unit
+
+    val OutOfConeFilesAreAddedAsLinks     : VisualStudio -> bool
+    val SupportsOutputWindowPane     : VisualStudio -> bool
+
+
+    /// True if files outside of the project cone are added as links.
+    val AutoCompleteMemberDataTipsThrowsScope : VisualStudio * string -> System.IDisposable
+
+    
+    val CreateSingleFileProject      : VisualStudio * string -> (OpenSolution * OpenProject * OpenFile)
+    val CreateNamedSingleFileProject : VisualStudio * (string * string) -> (OpenSolution * OpenProject * OpenFile)
+    val GetMatchingBracesForPositionAtCursor : OpenFile -> (TextSpan * TextSpan) array
+    
+    // ------------------------------------------------------------------------
+
+    // Methods to simplify testing of specific features
+
+    type SetMarkerPoint =
+        | StartOfMarker
+        | EndOfMarker
+
+    // Navigation items & regions
+    val AssertRegionListContains        : list<(int*int)*(int*int)> * list<NewHiddenRegion> -> unit
+    val AssertNavigationContains        : DropDownMember[] * string -> unit
+    val AssertNavigationContainsAll     : DropDownMember[] * seq<string> -> unit
+    
+    // Completion list
+    val AssertCompListIsEmpty           : CompletionItem[] -> unit
+    val AssertCompListContains          : CompletionItem[] * string -> unit
+    val AssertCompListDoesNotContain    : CompletionItem[] * string -> unit
+    val AssertCompListContainsAll       : CompletionItem[] * string list -> unit
+    val AssertCompListContainsExactly   : CompletionItem[] * string list -> unit
+    val AssertCompListDoesNotContainAny : CompletionItem[] * string list -> unit
+
+    // Dot completion
+    val DotCompletionAtMarker        : SetMarkerPoint -> OpenFile -> string -> CompletionItem[]
+    val DotCompletionAtStartOfMarker : (OpenFile -> string -> CompletionItem[])
+    val DotCompletionAtEndOfMarker   : (OpenFile -> string -> CompletionItem[])
+    
+    
+    // Goto Definition
+    val GotoDefnFailure : (string * string) option
+    val GotoDefnSuccess : string -> string -> (string * string) option
+    
+    val CheckGotoDefnResult   : (string * string) option -> OpenFile -> GotoDefnResult -> unit
diff --git a/vsintegration/src/Salsa/VsMocks.fs b/vsintegration/src/Salsa/VsMocks.fs
new file mode 100644
index 0000000..ddf580d
--- /dev/null
+++ b/vsintegration/src/Salsa/VsMocks.fs
@@ -0,0 +1,1685 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+(*
+    Mocks of major Visual Studio interfaces.
+*)
+
+namespace Salsa
+
+open Microsoft.VisualStudio.FSharp.LanguageService
+open Microsoft.VisualStudio
+open Microsoft.VisualStudio.FSharp.LanguageService
+open Microsoft.VisualStudio.FSharp.ProjectSystem
+open Microsoft.VisualStudio.Shell
+open Microsoft.VisualStudio.Shell.Interop
+open Microsoft.VisualStudio.TextManager.Interop
+open Microsoft.VisualStudio.OLE.Interop
+open Microsoft.Build.BuildEngine
+open System.Diagnostics
+open Microsoft.Build.Execution
+open Microsoft.Build.Framework
+open System.Runtime.InteropServices
+open System
+open System.Collections.Generic
+
+module internal VsMocks = 
+    let private notimpl() = raise (new System.Exception("Not implemented"))
+    let private ok = VSConstants.S_OK
+    let private fail = VSConstants.E_FAIL
+    let private impl1 fo next a =
+        match fo with 
+            Some(f) -> 
+                match f a with | Some(r) -> r | _ -> next a
+            | _ -> next a
+    let private impl2 fo next a b =
+        match fo with 
+            Some(f) -> 
+                match f a b with | Some(r) -> r | _ -> next a b
+            | _ -> next a b
+    let private impl3 fo next a b c=
+        match fo with 
+            Some(f) -> 
+                match f a b c with | Some(r) -> r | _ -> next a b c
+            | _ -> next a b c
+    let private impl4 fo next a b c d=
+        match fo with 
+            Some(f) -> 
+                match f a b c d with | Some(r) -> r | _ -> next a b c d
+            | _ -> next a b c d
+    let private uimpl fo next = 
+        match fo with 
+                Some(f) -> 
+                    match f() with 
+                        Some(r)->r
+                      | None -> next()
+               | _ -> next()
+
+    type IDelegable<'a> = interface
+            abstract SetInner: 'a->unit
+            abstract GetInner: unit->'a
+        end
+
+    type VSITEMID=int32        
+
+
+    type VsFileChangeEx() = 
+        let fileToEvents = new Dictionary<string,IVsFileChangeEvents list>()
+        let Canonicalize (filename:string) = Internal.Utilities.FileSystem.Path.SafeGetFullPath(filename)
+        
+        member c.AddedFile(file) =
+//            printfn "VsMocks.VsFileChangeEx: Added file %s " file
+            c.SomehowModifiedFile(file, uint32 _VSFILECHANGEFLAGS.VSFILECHG_Add)
+        member c.DeletedFile(file) =
+//            printfn "VsMocks.VsFileChangeEx: Deleted file %s " file
+            c.SomehowModifiedFile(file, uint32 _VSFILECHANGEFLAGS.VSFILECHG_Del)
+        member c.ChangedFile(file) =
+//            printfn "VsMocks.VsFileChangeEx: Changed file %s " file
+            c.SomehowModifiedFile(file, uint32 _VSFILECHANGEFLAGS.VSFILECHG_Time)
+        member c.SomehowModifiedFile(file, how) =
+            let file = Canonicalize file
+            let CallFilesChanged(fce:IVsFileChangeEvents) =
+//                printfn "VsMocks.VsFileChangeEx: Calling FilesChanged callback for %s, how = %A " file how
+                fce.FilesChanged(1u,[|file|],[|how|])|>ignore
+            
+            match fileToEvents.TryGetValue(file) with
+            | true, events -> events |> List.iter CallFilesChanged
+            | false, _ -> ()
+            
+        interface IVsFileChangeEx with
+            member fc.AdviseFileChange(pszMkDocument,grfFilter,pFCE,vsCookie) = 
+                let pszMkDocument = Canonicalize pszMkDocument
+//                printfn "VsMocks.VsFileChangeEx: Advise %s " pszMkDocument
+                match fileToEvents.TryGetValue(pszMkDocument) with
+                | true, events -> fileToEvents.[pszMkDocument] <- pFCE :: events
+                | false, _ -> fileToEvents.Add(pszMkDocument, [pFCE])
+                vsCookie <- 0u
+                ok
+            member fc.UnadviseFileChange(vsCookie) = 
+//                printfn "VsMocks.VsFileChangeEx: Unadvise %d " vsCookie
+                ok
+            member fc.SyncFile(pszMkDocument) = notimpl()
+            member fc.IgnoreFile(vsCookie, pszMkDocument, fIgnore) = notimpl()
+            member fc.AdviseDirChange(pszDir, fWatchSubDir, pFCE,vsCookie) = notimpl()
+            member fc.UnadviseDirChange(vsCookie) = notimpl()
+    
+    /// Mockable versions of various VS interfaces. Use optional function parameters
+    /// so that we don't have to specify all of them.       
+    type Vs() = 
+        static let FSharpProjectGuid = new Guid(Microsoft.VisualStudio.FSharp.ProjectSystem.GuidList.guidFSharpProjectFactoryString)
+        
+        static member MakeTextView() = 
+            let userData = new Dictionary<Guid,obj>()
+            {new IVsTextView with
+                member tv.Initialize(pBuffer, hwndParent, initFlags, pInitView) = notimpl()
+                member tv.CloseView() = notimpl()
+                member tv.GetCaretPos(piLine, piColumn) = notimpl()
+                member tv.SetCaretPos(iLine, iColumn) = notimpl()
+                member tv.GetSelectionSpan(pSpan) = notimpl()
+                member tv.GetSelection(piAnchorLine, piAnchorCol, piEndLine,  piEndCol) = notimpl()
+                member tv.SetSelection(iAnchorLine, iAnchorCol, iEndLine, iEndCol) = notimpl()
+                member tv.GetSelectionMode() = notimpl()
+                member tv.SetSelectionMode(iSelMode) = notimpl()
+                member tv.ClearSelection(fMoveToAnchor) = notimpl()
+                member tv.CenterLines(iTopLine, iCount) = notimpl()
+                member tv.GetSelectedText(pbstrText) = notimpl()
+                member tv.GetSelectionDataObject(ppIDataObject) = notimpl()
+                member tv.GetTextStream(iTopLine, iTopCol, iBottomLine, iBottomCol, pbstrText) = notimpl()
+                member tv.SetBuffer(pBuffer) = notimpl()
+                member tv.GetWindowHandle() = notimpl()
+                member tv.GetScrollInfo(iBar, piMinUnit, piMaxUnit, piVisibleUnits, piFirstVisibleUnit) = notimpl()
+                member tv.SetScrollPosition(iBar, iFirstVisibleUnit) = notimpl()
+                member tv.AddCommandFilter(pNewCmdTarg, ppNextCmdTarg) = notimpl()
+                member tv.RemoveCommandFilter(pCmdTarg) = notimpl()
+                member tv.UpdateCompletionStatus(pCompSet, dwFlags) = notimpl()
+                member tv.UpdateTipWindow(pTipWindow, dwFlags) = notimpl()
+                member tv.GetWordExtent(iLine, iCol, dwFlags, pSpan) = notimpl()
+                member tv.RestrictViewRange(iMinLine, iMaxLine,   pClient) = notimpl()
+                member tv.ReplaceTextOnLine(iLine, iStartCol, iCharsToReplace, pszNewText, iNewLen) = notimpl()
+                member tv.GetLineAndColumn(iPos, piLine, piIndex) = notimpl()
+                member tv.GetNearestPosition(iLine, iCol, piPos, piVirtualSpaces) = notimpl()
+                member tv.UpdateViewFrameCaption() = notimpl()
+                member tv.CenterColumns(iLine, iLeftCol, iColCount) = notimpl()
+                member tv.EnsureSpanVisible(span) = notimpl()
+                member tv.PositionCaretForEditing(iLine, cIndentLevels) = notimpl()
+                member tv.GetPointOfLineColumn(iLine, iCol, ppt) = notimpl()
+                member tv.GetLineHeight(piLineHeight) = notimpl()
+                member tv.HighlightMatchingBrace(dwFlags, cSpans, rgBaseSpans) = notimpl()
+                member tv.SendExplicitFocus() = notimpl()
+                member tv.SetTopLine(iBaseLine) = notimpl()
+                member tv.GetBuffer(ppbuffer) = notimpl()
+            interface IVsLayeredTextView with
+                member ltv.GetSelectedAtom(dwFlags, ppunkAtom) = notimpl()
+                member ltv.GetRelativeSelectionState(dwFlags, pReferenceLayer, pSelState) = notimpl()
+                member ltv.SetRelativeSelectionState(dwFlags, pReferenceLayer, pSelState) = notimpl()
+                member ltv.GetTopmostLayer(ppLayer) = notimpl()
+            interface IVsUserData with
+                member x.SetData(guid,obj) =
+                    if userData.ContainsKey(guid) then userData.Remove(guid) |> ignore
+                    match obj with
+                    |   null -> ()
+                    |   _   -> userData.Add(guid,obj) |> ignore
+                    VSConstants.S_OK
+                member x.GetData(guid,obj) =
+                    if userData.ContainsKey(guid) then 
+                        obj <- userData.[guid]
+                    else
+                        obj <- null
+                    VSConstants.S_OK
+            }
+        
+        
+        static member VsUserContext(?addAttribute) =
+            { new IVsUserContext with
+                member this.AddAttribute (usage,key,value) =
+                    match addAttribute with
+                    |   Some f -> f (usage,key,value)
+                    |   None -> notimpl()
+                member this.AddSubcontext(_,_,_) = notimpl()
+                member this.AdviseUpdate(_,_) = notimpl()
+                member this.CountAttributes(_,_,_) = notimpl()
+                member this.RemoveAttribute(_,_) = notimpl()
+                member this.RemoveSubcontext _ = notimpl()
+                member this.GetAttribute(_,_,_,_,_) = notimpl()
+                member this.CountSubcontexts _ = notimpl()
+                member this.GetSubcontext(_,_) = notimpl()
+                member this.IsDirty _ = notimpl()
+                member this.SetDirty _ = notimpl()
+                member this.Update () = notimpl()
+                member this.UnadviseUpdate _ = notimpl()
+                member this.GetAttrUsage(_,_,_) = notimpl()
+                member this.RemoveAllSubcontext () = notimpl()
+                member this.GetPriority _ = notimpl()
+                member this.RemoveAttributeIncludeChildren(_,_) = notimpl()
+                member this.GetAttributePri(_,_,_,_,_,_) = notimpl()
+            }
+        
+        static member DelegateTextView(oldtv:IVsTextView, ?getBuffer, ?getScrollInfo, ?getTopmostLayer) = 
+            let inner:Ref<IVsTextView> = ref oldtv
+            {new IVsTextView with
+                member tv.Initialize(pBuffer, hwndParent, initFlags, pInitView) = (!inner).Initialize(pBuffer, hwndParent, initFlags, pInitView)
+                member tv.CloseView() = (!inner).CloseView()
+                member tv.GetCaretPos(piLine, piColumn) = (!inner).GetCaretPos(ref piLine, ref piColumn)
+                member tv.SetCaretPos(iLine, iColumn) = (!inner).SetCaretPos(iLine, iColumn)
+                member tv.GetSelectionSpan(pSpan) = (!inner).GetSelectionSpan(pSpan)
+                member tv.GetSelection(piAnchorLine, piAnchorCol, piEndLine,  piEndCol) = (!inner).GetSelection(ref piAnchorLine, ref piAnchorCol, ref piEndLine,  ref piEndCol)
+                member tv.SetSelection(iAnchorLine, iAnchorCol, iEndLine, iEndCol) = (!inner).SetSelection(iAnchorLine, iAnchorCol, iEndLine, iEndCol)
+                member tv.GetSelectionMode() = (!inner).GetSelectionMode()
+                member tv.SetSelectionMode(iSelMode) = (!inner).SetSelectionMode(iSelMode)
+                member tv.ClearSelection(fMoveToAnchor) = (!inner).ClearSelection(fMoveToAnchor)
+                member tv.CenterLines(iTopLine, iCount) = (!inner).CenterLines(iTopLine, iCount)
+                member tv.GetSelectedText(pbstrText) = (!inner).GetSelectedText(ref pbstrText)
+                member tv.GetSelectionDataObject(ppIDataObject) = (!inner).GetSelectionDataObject(ref ppIDataObject)
+                member tv.GetTextStream(iTopLine, iTopCol, iBottomLine, iBottomCol, pbstrText) = (!inner).GetTextStream(iTopLine, iTopCol, iBottomLine, iBottomCol, ref pbstrText)
+                member tv.SetBuffer(pBuffer) = (!inner).SetBuffer(pBuffer)
+                member tv.GetWindowHandle() = (!inner).GetWindowHandle()
+                member tv.GetScrollInfo(iBar, piMinUnit, piMaxUnit, piVisibleUnits, piFirstVisibleUnit) = 
+                    let next bar = (!inner).GetScrollInfo(bar)
+                    let hr,minu,maxu,visu,firstvis= impl1 getScrollInfo next iBar
+                    piMinUnit<-minu
+                    piMaxUnit<-maxu
+                    piVisibleUnits<-visu
+                    piFirstVisibleUnit<-firstvis
+                    hr
+                member tv.SetScrollPosition(iBar, iFirstVisibleUnit) = (!inner).SetScrollPosition(iBar, iFirstVisibleUnit)
+                member tv.AddCommandFilter(pNewCmdTarg, ppNextCmdTarg) = (!inner).AddCommandFilter(pNewCmdTarg, ref ppNextCmdTarg)
+                member tv.RemoveCommandFilter(pCmdTarg) = (!inner).RemoveCommandFilter(pCmdTarg)
+                member tv.UpdateCompletionStatus(pCompSet, dwFlags) = (!inner).UpdateCompletionStatus(pCompSet, dwFlags)
+                member tv.UpdateTipWindow(pTipWindow, dwFlags) = (!inner).UpdateTipWindow(pTipWindow, dwFlags)
+                member tv.GetWordExtent(iLine, iCol, dwFlags, pSpan) = (!inner).GetWordExtent(iLine, iCol, dwFlags, pSpan)
+                member tv.RestrictViewRange(iMinLine, iMaxLine,   pClient) = (!inner).RestrictViewRange(iMinLine, iMaxLine,   pClient)
+                member tv.ReplaceTextOnLine(iLine, iStartCol, iCharsToReplace, pszNewText, iNewLen) = (!inner).ReplaceTextOnLine(iLine, iStartCol, iCharsToReplace, pszNewText, iNewLen)
+                member tv.GetLineAndColumn(iPos, piLine, piIndex) = (!inner).GetLineAndColumn(iPos, ref piLine, ref piIndex)
+                member tv.GetNearestPosition(iLine, iCol, piPos, piVirtualSpaces) = (!inner).GetNearestPosition(iLine, iCol, ref piPos, ref piVirtualSpaces)
+                member tv.UpdateViewFrameCaption() = (!inner).UpdateViewFrameCaption()
+                member tv.CenterColumns(iLine, iLeftCol, iColCount) = (!inner).CenterColumns(iLine, iLeftCol, iColCount)
+                member tv.EnsureSpanVisible(span) = (!inner).EnsureSpanVisible(span)
+                member tv.PositionCaretForEditing(iLine, cIndentLevels) = (!inner).PositionCaretForEditing(iLine, cIndentLevels)
+                member tv.GetPointOfLineColumn(iLine, iCol, ppt) = (!inner).GetPointOfLineColumn(iLine, iCol, ppt)
+                member tv.GetLineHeight(piLineHeight) = (!inner).GetLineHeight(ref piLineHeight)
+                member tv.HighlightMatchingBrace(dwFlags, cSpans, rgBaseSpans) = (!inner).HighlightMatchingBrace(dwFlags, cSpans, rgBaseSpans)
+                member tv.SendExplicitFocus() = (!inner).SendExplicitFocus()
+                member tv.SetTopLine(iBaseLine) = (!inner).SetTopLine(iBaseLine)
+                member tv.GetBuffer(ppbuffer) = 
+                    let next() = (!inner).GetBuffer()
+                    let hr,buf = uimpl getBuffer next
+                    ppbuffer<-buf
+                    hr
+            interface IVsLayeredTextView with
+                member ltv.GetSelectedAtom(dwFlags, ppunkAtom) = notimpl()
+                member ltv.GetRelativeSelectionState(dwFlags, pReferenceLayer, pSelState) = notimpl()
+                member ltv.SetRelativeSelectionState(dwFlags, pReferenceLayer, pSelState) = notimpl()
+                member ltv.GetTopmostLayer(ppLayer) = 
+                    let next() = ((box (!inner)):?>IVsLayeredTextView).GetTopmostLayer()
+                    let hr,l = uimpl getTopmostLayer next
+                    ppLayer<-l
+                    hr
+            interface IDelegable<IVsTextView> with
+                member id.GetInner() = !inner
+                member id.SetInner(i) = inner:=i
+            interface IVsUserData with
+                member ud.GetData(guid,o) = ((!inner) :?> IVsUserData).GetData(&guid,&o)
+                member ud.SetData(guid,o) = ((!inner) :?> IVsUserData).SetData(&guid,o)
+             }                
+            
+        static member MakeTextLayer() =
+           {new IVsTextLayer with
+                member tl.LocalLineIndexToBase(iLocalLine, iLocalIndex, piBaseLine, piBaseIndex) = notimpl()
+                member tl.BaseLineIndexToLocal(iBaseLine, iBaseIndex, piLocalLine, piLocalIndex) = notimpl()
+                member tl.LocalLineIndexToDeeperLayer(pTargetLayer, iLocalLine, iLocalIndex, piTargetLine, piTargetIndex) = notimpl()
+                member tl.DeeperLayerLineIndexToLocal(dwFlags, pTargetLayer, iLayerLine, iLayerIndex, piLocalLine, piLocalIndex) = notimpl()
+                member tl.GetBaseBuffer(ppiBuf) = notimpl()
+                member tl.LockBufferEx(dwFlags) = notimpl()
+                member tl.UnlockBufferEx(dwFlags) = notimpl()
+                member tl.GetLengthOfLine(iLine, piLength) = notimpl()
+                member tl.GetLineCount(piLineCount) = notimpl()
+                member tl.GetLastLineIndex(piLine, piIndex) = notimpl()
+                member tl.GetMarkerData(iTopLine, iBottomLine, pMarkerData) = notimpl()
+                member tl.ReleaseMarkerData(pMarkerData) = notimpl()
+                member tl.GetLineDataEx(dwFlags, iLine, iStartIndex, iEndIndex, pLineData, pMarkerData) = notimpl()
+                member tl.ReleaseLineDataEx(pLineData) = notimpl()
+                member tl.GetLineText(iStartLine, iStartIndex, iEndLine, iEndIndex, pbstrBuf) = notimpl()
+                member tl.CopyLineText(iStartLine, iStartIndex, iEndLine, iEndIndex, pszBuf, pcchBuf) = notimpl()
+                member tl.ReplaceLines(iStartLine, iStartIndex, iEndLine, iEndIndex, pszText, iNewLen, pChangedSpan) = notimpl()
+                member tl.CanReplaceLines(iStartLine, iStartIndex, iEndLine, iEndIndex, iNewLen) = notimpl()
+                member tl.CreateTrackingPoint(iLine, iIndex, ppMarker) = notimpl()
+                member tl.EnumLayerMarkers(iStartLine, iStartIndex, iEndLine, iEndIndex, iMarkerType, dwFlags, ppEnum) = notimpl()
+                member tl.ReplaceLinesEx(dwFlags, iStartLine, iStartIndex, iEndLine, iEndIndex, pszText, iNewLen, pChangedSpan) = notimpl()
+                member tl.MapLocalSpansToTextOriginatingLayer(dwFlags, pLocalSpanEnum, ppTargetLayer, ppTargetSpanEnum) = notimpl()
+           }
+        static member DelegateTextLayer(oldtl:IVsTextLayer, ?localLineIndexToBase) = 
+            let inner = ref oldtl
+            {new IVsTextLayer with
+                member tl.LocalLineIndexToBase(iLocalLine, iLocalIndex, piBaseLine, piBaseIndex) = 
+                    let next ll li = (!inner).LocalLineIndexToBase(ll,li)
+                    let hr,bl,bi = impl2 localLineIndexToBase next iLocalLine iLocalIndex
+                    piBaseLine<-bl
+                    piBaseIndex<-bi
+                    hr
+                member tl.BaseLineIndexToLocal(iBaseLine, iBaseIndex, piLocalLine, piLocalIndex) = notimpl()
+                member tl.LocalLineIndexToDeeperLayer(pTargetLayer, iLocalLine, iLocalIndex, piTargetLine, piTargetIndex) = notimpl() 
+                member tl.DeeperLayerLineIndexToLocal(dwFlags, pTargetLayer, iLayerLine, iLayerIndex, piLocalLine, piLocalIndex) = notimpl()
+                member tl.GetBaseBuffer(ppiBuf) = notimpl()
+                member tl.LockBufferEx(dwFlags) = notimpl()
+                member tl.UnlockBufferEx(dwFlags) = notimpl()
+                member tl.GetLengthOfLine(iLine, piLength) = notimpl()
+                member tl.GetLineCount(piLineCount) = notimpl()
+                member tl.GetLastLineIndex(piLine, piIndex) = notimpl()
+                member tl.GetMarkerData(iTopLine, iBottomLine, pMarkerData) = notimpl()
+                member tl.ReleaseMarkerData(pMarkerData) = notimpl()
+                member tl.GetLineDataEx(dwFlags, iLine, iStartIndex, iEndIndex, pLineData, pMarkerData) = notimpl()
+                member tl.ReleaseLineDataEx(pLineData) = notimpl()
+                member tl.GetLineText(iStartLine, iStartIndex, iEndLine, iEndIndex, pbstrBuf) = notimpl()
+                member tl.CopyLineText(iStartLine, iStartIndex, iEndLine, iEndIndex, pszBuf, pcchBuf) = notimpl()
+                member tl.ReplaceLines(iStartLine, iStartIndex, iEndLine, iEndIndex, pszText, iNewLen, pChangedSpan) = notimpl()
+                member tl.CanReplaceLines(iStartLine, iStartIndex, iEndLine, iEndIndex, iNewLen) = notimpl()
+                member tl.CreateTrackingPoint(iLine, iIndex, ppMarker) = notimpl()
+                member tl.EnumLayerMarkers(iStartLine, iStartIndex, iEndLine, iEndIndex, iMarkerType, dwFlags, ppEnum) = notimpl()
+                member tl.ReplaceLinesEx(dwFlags, iStartLine, iStartIndex, iEndLine, iEndIndex, pszText, iNewLen, pChangedSpan) = notimpl()
+                member tl.MapLocalSpansToTextOriginatingLayer(dwFlags, pLocalSpanEnum, ppTargetLayer, ppTargetSpanEnum) = notimpl()            
+             interface IDelegable<IVsTextLayer> with
+                member id.GetInner() = !inner
+                member id.SetInner(i) = inner:=i
+            }
+            
+        static member MakeTextLineMarker() =
+            let markerSpan = ref (new TextSpan(iStartLine = 0, iEndLine = 0, iStartIndex = 0, iEndIndex = 0))
+            {new IVsTextLineMarker with
+                member tl.DrawGlyph(hdc, pRect) = notimpl()
+                member tl.ExecMarkerCommand(iItem) = notimpl()
+                member tl.GetBehavior(pdwBehavior) = notimpl()
+                member tl.GetCurrentSpan(pSpan) = pSpan.[0] <- !markerSpan ; 0
+                member tl.GetLineBuffer(ppBuffer) = notimpl()
+                member tl.GetMarkerCommandInfo(iItem, pbstrText, pcmdf) = notimpl()
+                member tl.GetPriorityIndex(piPriorityIndex) = notimpl()
+                member tl.GetTipText(pbstrText) = notimpl()
+                member tl.GetType(piMarkerType) = notimpl()
+                member tl.GetVisualStyle(pdwFlags) = notimpl()
+                member tl.Invalidate() = 0
+                member tl.ResetSpan(iSL, iSI, iEL, iEI) = 
+                    markerSpan := new TextSpan(iStartLine = iSL, iEndLine = iEL, iStartIndex = iSI, iEndIndex = iEI) ; 
+                    0
+                member tl.SetBehavior(dwBehavior) = notimpl()
+                member tl.SetType(iMarkerType) = notimpl()
+                member tl.SetVisualStyle(dwFlags) = notimpl()
+                member tl.UnadviseClient() = 0
+                
+            interface IVsTextMarker with
+                member tl.DrawGlyph(hdc, pRect) = notimpl()
+                member tl.ExecMarkerCommand(iItem) = notimpl()
+                member tl.GetBehavior(pdwBehavior) = notimpl()
+                member tl.GetMarkerCommandInfo(iItem, pbstrText, pcmdf) = notimpl()
+                member tl.GetPriorityIndex(piPriorityIndex) = notimpl()
+                member tl.GetTipText(pbstrText) = notimpl()
+                member tl.GetType(piMarkerType) = notimpl()
+                member tl.GetVisualStyle(pdwFlags) = notimpl();
+                member tl.Invalidate() = notimpl()
+                member tl.SetBehavior(dwBehavior) = notimpl()
+                member tl.SetType(iMarkerType) = notimpl()
+                member tl.SetVisualStyle(dwFlags) = notimpl()
+                member tl.UnadviseClient() = notimpl()
+            }
+
+        static member MakeTextLines() =
+           let userData = new Dictionary<Guid,obj>()
+           {new IVsTextLines with
+                member tl.LockBuffer() = notimpl()
+                member tl.UnlockBuffer() = notimpl()
+                member tl.InitializeContent(pszText, iLength) = notimpl()
+                member tl.GetStateFlags(pdwReadOnlyFlags) = notimpl()
+                member tl.SetStateFlags(flags) = notimpl()
+                member tl.GetPositionOfLine(line,position) = notimpl()
+                member tl.GetPositionOfLineIndex(line, index, x) = notimpl()
+                member tl.GetLineIndexOfPosition(position, line, x) = notimpl()
+                member tl.GetLengthOfLine(line, length) = notimpl()
+                member tl.GetLineCount(x) = notimpl()
+                member tl.GetSize(x) = notimpl()
+                member tl.GetLanguageServiceID(pguidLangService:System.Guid byref) : System.Int32 = notimpl()
+                member tl.SetLanguageServiceID(guidLangServ) = notimpl()
+                member tl.GetUndoManager(x) = notimpl()
+                member tl.Reserved1() = notimpl()
+                member tl.Reserved2() = notimpl()
+                member tl.Reserved3() = notimpl()
+                member tl.Reserved4() = notimpl()
+                member tl.Reload(undoable) = notimpl()
+                member tl.LockBufferEx(flags) = notimpl()
+                member tl.UnlockBufferEx(flags) = notimpl()
+                member tl.GetLastLineIndex(x,y) = notimpl()
+                member tl.Reserved5() = notimpl()
+                member tl.Reserved6() = notimpl()
+                member tl.Reserved7() = notimpl()
+                member tl.Reserved8() = notimpl()
+                member tl.Reserved9() = notimpl()
+                member tl.Reserved10() = notimpl()
+                member tl.GetMarkerData(iTopLine, iBottomLine, pMarkerData)= notimpl()
+                member tl.ReleaseMarkerData(pMarkerData)= notimpl()
+                member tl.GetLineData(iLine, pLineData, pMarkerData)= notimpl()
+                member tl.ReleaseLineData(pLineData)= notimpl()
+                member tl.GetLineText(iStartLine, iStartIndex, iEndLine, iEndIndex, pbstrBuf) = notimpl()
+                member tl.CopyLineText(iStartLine, iStartIndex, iEndLine, iEndIndex, pszBuf, pcchBuf)= notimpl()
+                member tl.ReplaceLines(iStartLine, iStartIndex, iEndLine, iEndIndex, pszText, iNewLen, pChangedSpan)= notimpl()
+                member tl.CanReplaceLines(iStartLine, iStartIndex, iEndLine, iEndIndex, iNewLen)= notimpl()
+                member tl.CreateLineMarker(iMarkerType, iStartLine, iStartIndex, iEndLine, iEndIndex, pClient, ppMarker)= 
+                    let textLineMarker = Vs.MakeTextLineMarker()
+                    textLineMarker.ResetSpan(iStartLine, iStartIndex, iEndLine, iEndIndex) |> ignore
+                    ppMarker.[0] <- textLineMarker ;
+                    0
+                member tl.EnumMarkers(iStartLine, iStartIndex, iEndLine, iEndIndex, iMarkerType, udwFlags, ppEnum)= notimpl()
+                member tl.FindMarkerByLineIndex(iMarkerType, iStartingLine, iStartingIndex, udwFlags, ppMarker)= notimpl()
+                member tl.AdviseTextLinesEvents(pSink, updwCookie)= notimpl()
+                member tl.UnadviseTextLinesEvents(udwCookie)= notimpl()
+                member tl.GetPairExtents(pSpanIn, pSpanOut)= notimpl()
+                member tl.ReloadLines(iStartLine, iStartIndex, iEndLine, iEndIndex, pszText, iNewLen, pChangedSpan)= notimpl()
+                member tl.IVsTextLinesReserved1(iLine, pLineData, fAttributes)= notimpl()
+                member tl.GetLineDataEx(udwFlags, iLine, iStartIndex, iEndIndex, pLineData, pMarkerData)= notimpl()
+                member tl.ReleaseLineDataEx(pLineData)= notimpl()
+                member tl.CreateEditPoint(iLine, iIndex, ppEditPoint)= notimpl()
+                member tl.ReplaceLinesEx(udwFlags, iStartLine, iStartIndex, iEndLine, iEndIndex, pszText, iNewLen, pChangedSpan)= notimpl()
+                member tl.CreateTextPoint(iLine, iIndex, ppTextPoint)= notimpl()
+
+            interface IVsTextBuffer with 
+                member tl.LockBuffer() = notimpl()
+                member tl.UnlockBuffer() = notimpl()
+                member tl.InitializeContent(pszText, iLength) = notimpl()
+                member tl.GetStateFlags(pdwReadOnlyFlags) = notimpl()
+                member tl.SetStateFlags(flags) = notimpl()
+                member tl.GetPositionOfLine(line,position) = notimpl()
+                member tl.GetPositionOfLineIndex(line, index, x) = notimpl()
+                member tl.GetLineIndexOfPosition(position, line, x) = notimpl()
+                member tl.GetLengthOfLine(line, length) = notimpl()
+                member tl.GetLineCount(x) = notimpl()
+                member tl.GetSize(x) = notimpl()
+                member tl.GetLanguageServiceID(pguidLangService:System.Guid byref) : System.Int32 = notimpl()
+                member tl.SetLanguageServiceID(guidLangServ) = notimpl()
+                member tl.GetUndoManager(x) = notimpl()
+                member tl.Reserved1() = notimpl()
+                member tl.Reserved2() = notimpl()
+                member tl.Reserved3() = notimpl()
+                member tl.Reserved4() = notimpl()
+
+                member tl.Reload(undoable) = notimpl()
+                member tl.LockBufferEx(flags) = notimpl()
+                member tl.UnlockBufferEx(flags) = notimpl()
+                member tl.GetLastLineIndex(x,y) = notimpl()
+                member tl.Reserved5() = notimpl()
+                member tl.Reserved6() = notimpl()
+                member tl.Reserved7() = notimpl()
+                member tl.Reserved8() = notimpl()
+                member tl.Reserved9() = notimpl()
+                member tl.Reserved10() = notimpl()
+
+            interface IVsTextColorState with   
+                member tcs.ReColorizeLines(iTopLine, iBottomLine) = notimpl()
+                member tcs.GetColorStateAtStartOfLine(iLine, piState) = notimpl()
+                
+            interface IVsUserData with
+                member x.SetData(guid,obj) =
+                    if userData.ContainsKey(guid) then userData.Remove(guid) |> ignore
+                    match obj with
+                    |   null -> ()
+                    |   _   -> userData.Add(guid,obj) |> ignore
+                    VSConstants.S_OK
+                member x.GetData(guid,obj) =
+                    if userData.ContainsKey(guid) then 
+                        obj <- userData.[guid]
+                    else
+                        obj <- null
+                    VSConstants.S_OK
+            }
+        static member DelegateTextLines(oldtl:IVsTextLines, ?getLengthOfLine, ?getLineText, ?getLineCount, ?recolorizeLines, ?getColorStateAtStartOfLine, ?getData) = 
+            let inner:Ref<IVsTextLines> = ref oldtl
+            {new IVsTextLines with
+                member tl.LockBuffer() = (!inner).LockBuffer()
+                member tl.UnlockBuffer() = (!inner).UnlockBuffer()
+                member tl.InitializeContent(pszText, iLength) = (!inner).InitializeContent(pszText, iLength)
+                member tl.GetStateFlags(pdwReadOnlyFlags) = (!inner).GetStateFlags(ref pdwReadOnlyFlags)
+                member tl.SetStateFlags(flags) = (!inner).SetStateFlags(flags)
+                member tl.GetPositionOfLine(line,position) = (!inner).GetPositionOfLine(line, ref position)
+                member tl.GetPositionOfLineIndex(line, index, x) = (!inner).GetPositionOfLineIndex(line, index, ref x)
+                member tl.GetLineIndexOfPosition(position, line, x) = (!inner).GetLineIndexOfPosition(position, ref line, ref x)
+                member tl.GetLengthOfLine(line, length) = 
+                    let next line = (!inner).GetLengthOfLine(line)
+                    let hr,l = impl1 getLengthOfLine next line
+                    length<-l
+                    hr 
+                member tl.GetLineCount(count) = 
+                    let next () = (!inner).GetLineCount()
+                    let hr,c = uimpl getLineCount next 
+                    count<-c
+                    hr                     
+                member tl.GetSize(x) = (!inner).GetSize(ref x)
+                member tl.GetLanguageServiceID(pguidLangService:System.Guid byref)  = (!inner).GetLanguageServiceID(ref pguidLangService) 
+                member tl.SetLanguageServiceID(guidLangServ) = (!inner).SetLanguageServiceID(ref guidLangServ)
+                member tl.GetUndoManager(x) = (!inner).GetUndoManager(ref x)
+                member tl.Reserved1() = (!inner).Reserved1()
+                member tl.Reserved2() = (!inner).Reserved2()
+                member tl.Reserved3() = (!inner).Reserved3()
+                member tl.Reserved4() = (!inner).Reserved4()
+                member tl.Reload(undoable) = (!inner).Reload(undoable)
+                member tl.LockBufferEx(flags) = (!inner).LockBufferEx(flags)
+                member tl.UnlockBufferEx(flags) = (!inner).UnlockBufferEx(flags)
+                member tl.GetLastLineIndex(x,y) = (!inner).GetLastLineIndex(ref x,ref y)
+                member tl.Reserved5() = (!inner).Reserved5()
+                member tl.Reserved6() = (!inner).Reserved6()
+                member tl.Reserved7() = (!inner).Reserved7()
+                member tl.Reserved8() = (!inner).Reserved8()
+                member tl.Reserved9() = (!inner).Reserved9()
+                member tl.Reserved10() = (!inner).Reserved10()
+                member tl.GetMarkerData(iTopLine, iBottomLine, pMarkerData) = (!inner).GetMarkerData(iTopLine, iBottomLine, pMarkerData)
+                member tl.ReleaseMarkerData(pMarkerData) = (!inner).ReleaseMarkerData(pMarkerData)
+                member tl.GetLineData(iLine, pLineData, pMarkerData) = (!inner).GetLineData(iLine, pLineData, pMarkerData)
+                member tl.ReleaseLineData(pLineData)= (!inner).ReleaseLineData(pLineData)
+                member tl.GetLineText(iStartLine, iStartIndex, iEndLine, iEndIndex, pbstrBuf) = 
+                    let next a b c d = (!inner).GetLineText(a,b,c,d) 
+                    let hr,b = impl4 getLineText next iStartLine iStartIndex iEndLine iEndIndex
+                    pbstrBuf<-b
+                    hr                     
+                member tl.CopyLineText(iStartLine, iStartIndex, iEndLine, iEndIndex, pszBuf, pcchBuf)= (!inner).CopyLineText(iStartLine, iStartIndex, iEndLine, iEndIndex, pszBuf, ref pcchBuf)
+                member tl.ReplaceLines(iStartLine, iStartIndex, iEndLine, iEndIndex, pszText, iNewLen, pChangedSpan)= (!inner).ReplaceLines(iStartLine, iStartIndex, iEndLine, iEndIndex, pszText, iNewLen, pChangedSpan)
+                member tl.CanReplaceLines(iStartLine, iStartIndex, iEndLine, iEndIndex, iNewLen)= (!inner).CanReplaceLines(iStartLine, iStartIndex, iEndLine, iEndIndex, iNewLen)
+                member tl.CreateLineMarker(iMarkerType, iStartLine, iStartIndex, iEndLine, iEndIndex, pClient, ppMarker)= (!inner).CreateLineMarker(iMarkerType, iStartLine, iStartIndex, iEndLine, iEndIndex, pClient, ppMarker)
+                member tl.EnumMarkers(iStartLine, iStartIndex, iEndLine, iEndIndex, iMarkerType, udwFlags, ppEnum)= (!inner).EnumMarkers(iStartLine, iStartIndex, iEndLine, iEndIndex, iMarkerType, udwFlags, ref ppEnum)
+                member tl.FindMarkerByLineIndex(iMarkerType, iStartingLine, iStartingIndex, udwFlags, ppMarker)= (!inner).FindMarkerByLineIndex(iMarkerType, iStartingLine, iStartingIndex, udwFlags, ref ppMarker)
+                member tl.AdviseTextLinesEvents(pSink, updwCookie)= (!inner).AdviseTextLinesEvents(pSink, ref updwCookie)
+                member tl.UnadviseTextLinesEvents(udwCookie)= (!inner).UnadviseTextLinesEvents(udwCookie)
+                member tl.GetPairExtents(pSpanIn, pSpanOut)= (!inner).GetPairExtents(pSpanIn, pSpanOut)
+                member tl.ReloadLines(iStartLine, iStartIndex, iEndLine, iEndIndex, pszText, iNewLen, pChangedSpan)= (!inner).ReloadLines(iStartLine, iStartIndex, iEndLine, iEndIndex, pszText, iNewLen, pChangedSpan)
+                member tl.IVsTextLinesReserved1(iLine, pLineData, fAttributes)= (!inner).IVsTextLinesReserved1(iLine, pLineData, fAttributes)
+                member tl.GetLineDataEx(udwFlags, iLine, iStartIndex, iEndIndex, pLineData, pMarkerData)= (!inner).GetLineDataEx(udwFlags, iLine, iStartIndex, iEndIndex, pLineData, pMarkerData)
+                member tl.ReleaseLineDataEx(pLineData)= (!inner).ReleaseLineDataEx(pLineData)
+                member tl.CreateEditPoint(iLine, iIndex, ppEditPoint)= (!inner).CreateEditPoint(iLine, iIndex, ref ppEditPoint)
+                member tl.ReplaceLinesEx(udwFlags, iStartLine, iStartIndex, iEndLine, iEndIndex, pszText, iNewLen, pChangedSpan)= (!inner).ReplaceLinesEx(udwFlags, iStartLine, iStartIndex, iEndLine, iEndIndex, pszText, iNewLen, pChangedSpan)
+                member tl.CreateTextPoint(iLine, iIndex, ppTextPoint)= (!inner).CreateTextPoint(iLine, iIndex, ref ppTextPoint)
+
+             interface IVsTextBuffer with 
+                member tl.LockBuffer() = (!inner).LockBuffer()
+                member tl.UnlockBuffer() = (!inner).UnlockBuffer()
+                member tl.InitializeContent(pszText, iLength) = (!inner).InitializeContent(pszText, iLength)
+                member tl.GetStateFlags(pdwReadOnlyFlags) = (!inner).GetStateFlags(ref pdwReadOnlyFlags)
+                member tl.SetStateFlags(flags) = (!inner).SetStateFlags(flags)
+                member tl.GetPositionOfLine(line,position) = (!inner).GetPositionOfLine(line, ref position)
+                member tl.GetPositionOfLineIndex(line, index, x) = (!inner).GetPositionOfLineIndex(line, index, ref x)
+                member tl.GetLineIndexOfPosition(position, line, x) = (!inner).GetLineIndexOfPosition(position, ref line, ref x)
+                member tl.GetLengthOfLine(line, length) = 
+                    let next line = (!inner).GetLengthOfLine(line)
+                    let hr,l = impl1 getLengthOfLine next line
+                    length<-l
+                    hr 
+                member tl.GetLineCount(x) = (!inner).GetLineCount(ref x)
+                member tl.GetSize(x) = (!inner).GetSize(ref x)
+                member tl.GetLanguageServiceID(pguidLangService:System.Guid byref)  = (!inner).GetLanguageServiceID(ref pguidLangService) 
+                member tl.SetLanguageServiceID(guidLangServ) = (!inner).SetLanguageServiceID(ref guidLangServ)
+                member tl.GetUndoManager(x) = (!inner).GetUndoManager(ref x)
+                member tl.Reserved1() = (!inner).Reserved1()
+                member tl.Reserved2() = (!inner).Reserved2()
+                member tl.Reserved3() = (!inner).Reserved3()
+                member tl.Reserved4() = (!inner).Reserved4()
+                member tl.Reload(undoable) = (!inner).Reload(undoable)
+                member tl.LockBufferEx(flags) = (!inner).LockBufferEx(flags)
+                member tl.UnlockBufferEx(flags) = (!inner).UnlockBufferEx(flags)
+                member tl.GetLastLineIndex(x,y) = (!inner).GetLastLineIndex(ref x,ref y)
+                member tl.Reserved5() = (!inner).Reserved5()
+                member tl.Reserved6() = (!inner).Reserved6()
+                member tl.Reserved7() = (!inner).Reserved7()
+                member tl.Reserved8() = (!inner).Reserved8()
+                member tl.Reserved9() = (!inner).Reserved9()
+                member tl.Reserved10() = (!inner).Reserved10()
+
+            interface IVsTextColorState with   
+                member tcs.ReColorizeLines(iTopLine, iBottomLine) = 
+                    let next top bottom = ((box (!inner)):?>IVsTextColorState).ReColorizeLines(top, bottom)
+                    let hr:int = impl2 recolorizeLines next iTopLine iBottomLine
+                    hr
+                member tcs.GetColorStateAtStartOfLine(iLine, piState) = 
+                    let next iLine = ((box (!inner)):?>IVsTextColorState).GetColorStateAtStartOfLine(iLine)
+                    let hr,state = impl1 getColorStateAtStartOfLine next iLine
+                    piState<-state
+                    hr
+                    
+            interface IVsUserData with
+                member ud.GetData(riidKey,pvtData) = 
+                    let next riidKey = ((box (!inner)):?>IVsUserData).GetData(riidKey)
+                    let (hr:int),data = impl1 getData next (ref riidKey)
+                    pvtData<-data
+                    hr
+                member ud.SetData(riidKey,vtData) = ((box (!inner)):?>IVsUserData).SetData(ref riidKey,vtData)                    
+
+            interface IDelegable<IVsTextLines> with
+                member id.GetInner() = !inner
+                member id.SetInner(i) = inner:=i
+             }            
+            
+// (The RDT is no longer used by the product, but leaving in VsMocks/Salsa in case we need it again in the future            
+        static member MakeRunningDocumentTable() = 
+            {new IVsRunningDocumentTable with
+                member rdt.RegisterAndLockDocument(grfRDTLockType, pszMkDocument, pHier, itemid, punkDocData, pdwCookie) = notimpl()
+                member rdt.LockDocument(grfRDTLockType, dwCookie) = notimpl()
+                member rdt.UnlockDocument(grfRDTLockType, dwCookie) = notimpl()
+                member rdt.FindAndLockDocument(dwRDTLockType, pszMkDocument, ppHier, pitemid, ppunkDocData, pdwCookie) = fail
+                member rdt.RenameDocument(pszMkDocumentOld, pszMkDocumentNew, pHier, itemidNew) = notimpl()
+                member rdt.AdviseRunningDocTableEvents(pSink, pdwCookie) = notimpl()
+                member rdt.UnadviseRunningDocTableEvents(dwCookie) = notimpl()
+                member rdt.GetDocumentInfo(docCookie, pgrfRDTFlags, pdwReadLocks, pdwEditLocks, pbstrMkDocument, ppHier, pitemid, ppunkDocData) = notimpl()
+                member rdt.NotifyDocumentChanged(dwCookie, grfDocChanged) = notimpl()
+                member rdt.NotifyOnAfterSave(dwCookie) = notimpl()
+                member rdt.GetRunningDocumentsEnum(ppenum) = notimpl()
+                member rdt.SaveDocuments(grfSaveOpts, pHier, itemid, docCookie) = notimpl()
+                member rdt.NotifyOnBeforeSave(dwCookie) = notimpl()
+                member rdt.RegisterDocumentLockHolder(grfRDLH, dwCookie, pLockHolder, pdwLHCookie) = notimpl()
+                member rdt.UnregisterDocumentLockHolder(dwLHCookie) = notimpl()
+                member rdt.ModifyDocumentFlags(docCookie, grfFlags, fSet) = notimpl() }
+                
+        static member DelegateRunningDocumentTable(oldrdt:IVsRunningDocumentTable, ?getDocumentInfo, ?unadviseRunningDocTableEvents, ?findAndLockDocument) = 
+            let inner:Ref<IVsRunningDocumentTable> = ref oldrdt
+            {new IVsRunningDocumentTable with
+                member rdt.RegisterAndLockDocument(grfRDTLockType, pszMkDocument, pHier, itemid, punkDocData, pdwCookie) = (!inner).RegisterAndLockDocument(grfRDTLockType, pszMkDocument, pHier, itemid, punkDocData, ref pdwCookie)
+                member rdt.LockDocument(grfRDTLockType, dwCookie) = (!inner).LockDocument(grfRDTLockType, dwCookie)
+                member rdt.UnlockDocument(grfRDTLockType, dwCookie) = (!inner).UnlockDocument(grfRDTLockType, dwCookie)
+                member rdt.FindAndLockDocument(dwRDTLockType, pszMkDocument, ppHier, pitemid, ppunkDocData, pdwCookie) = 
+                    let next() = (!inner).FindAndLockDocument(dwRDTLockType,pszMkDocument)
+                    let (hr:int),hier,itemid,docData,cookie =  
+                        match findAndLockDocument with
+                            | Some(f) -> 
+                                match f dwRDTLockType pszMkDocument with
+                                    Some(r)-> r
+                                    | _ -> next()
+                            | _ -> next()
+                    ppHier<-hier
+                    pitemid<- itemid
+                    ppunkDocData<-docData
+                    pdwCookie <- cookie
+                    hr                
+                
+                member rdt.RenameDocument(pszMkDocumentOld, pszMkDocumentNew, pHier, itemidNew) = (!inner).RenameDocument(pszMkDocumentOld, pszMkDocumentNew, pHier, itemidNew)
+                member rdt.AdviseRunningDocTableEvents(pSink, pdwCookie) = (!inner).AdviseRunningDocTableEvents(pSink, ref pdwCookie)
+                member rdt.UnadviseRunningDocTableEvents(dwCookie) = 
+                    let next() = (!inner).UnadviseRunningDocTableEvents(dwCookie)
+                    let hr =  
+                        match unadviseRunningDocTableEvents with
+                            Some(f) -> 
+                                match f dwCookie with
+                                    Some(r)-> r
+                                    | _ -> next()
+                            | _ -> next()
+                    hr
+                member rdt.GetDocumentInfo(docCookie, pgrfRDTFlags, pdwReadLocks, pdwEditLocks, pbstrMkDocument, ppHier, pitemid, ppunkDocData) = 
+                    let next() = (!inner).GetDocumentInfo(docCookie)
+                    let hr,_,_,_,mkd,hier,itemid,docd =  
+                        match getDocumentInfo with
+                            Some(f) -> 
+                                match f docCookie with
+                                    Some(r)-> r
+                                    | _ -> next()
+                            | _ -> next()
+                    pbstrMkDocument<-mkd
+                    ppHier<- hier
+                    pitemid<-itemid
+                    ppunkDocData <- docd
+                    hr
+                        
+                member rdt.NotifyDocumentChanged(dwCookie, grfDocChanged) = (!inner).NotifyDocumentChanged(dwCookie, grfDocChanged)
+                member rdt.NotifyOnAfterSave(dwCookie) = (!inner).NotifyOnAfterSave(dwCookie)
+                member rdt.GetRunningDocumentsEnum(ppenum) = (!inner).GetRunningDocumentsEnum(ref ppenum)
+                member rdt.SaveDocuments(grfSaveOpts, pHier, itemid, docCookie) = (!inner).SaveDocuments(grfSaveOpts, pHier, itemid, docCookie)
+                member rdt.NotifyOnBeforeSave(dwCookie) = (!inner).NotifyOnBeforeSave(dwCookie)
+                member rdt.RegisterDocumentLockHolder(grfRDLH, dwCookie, pLockHolder, pdwLHCookie) = (!inner).RegisterDocumentLockHolder(grfRDLH, dwCookie, pLockHolder, ref pdwLHCookie)
+                member rdt.UnregisterDocumentLockHolder(dwLHCookie) = (!inner).UnregisterDocumentLockHolder(dwLHCookie)
+                member rdt.ModifyDocumentFlags(docCookie, grfFlags, fSet) = (!inner).ModifyDocumentFlags(docCookie, grfFlags, fSet) 
+             interface IDelegable<IVsRunningDocumentTable> with
+                member id.GetInner() = !inner
+                member id.SetInner(i) = inner:=i
+             }       
+// )             
+        static member MakeHierarchy(projectSiteFactory:IProvideProjectSite) = 
+            {new IVsHierarchy with
+                member h.SetSite(psp) = notimpl()
+                member h.GetSite(ppSP) = notimpl()
+                member h.QueryClose(pfCanClose) = notimpl()
+                member h.Close() = notimpl()
+                member h.GetGuidProperty(itemid, propid, pguid) = 
+                    pguid <- FSharpProjectGuid   
+                    VSConstants.S_OK
+                member h.SetGuidProperty(itemid, propid, rguid) = notimpl()
+                member h.GetProperty(itemid, propid, pvar) = notimpl()
+                member h.SetProperty(itemid, propid, var) = notimpl()
+                member h.GetNestedHierarchy(itemid, iidHierarchyNested, ppHierarchyNested, pitemidNested) = notimpl()
+                member h.GetCanonicalName(itemid, pbstrName) = notimpl()
+                member h.ParseCanonicalName(pszName, pitemid) = notimpl()
+                member h.Unused0() = notimpl()
+                member h.AdviseHierarchyEvents(pEventSink, pdwCookie) = notimpl()
+                member h.UnadviseHierarchyEvents(dwCookie) = notimpl()
+                member h.Unused1() = notimpl()
+                member h.Unused2() = notimpl()
+                member h.Unused3() = notimpl()
+                member h.Unused4() = notimpl()
+             interface IProvideProjectSite with
+                member x.GetProjectSite() = projectSiteFactory.GetProjectSite()
+            }
+            
+        static member DelegateHierarchy(oldh:IVsHierarchy, ?getCanonicalName, ?getProperty) = 
+            let inner = ref oldh
+            {new IVsHierarchy with            
+                member h.SetSite(psp) = (!inner).SetSite(psp)
+                member h.GetSite(ppSP) = (!inner).GetSite(ref ppSP)
+                member h.QueryClose(pfCanClose) = (!inner).QueryClose(ref pfCanClose)
+                member h.Close() = (!inner).Close()
+                member h.GetGuidProperty(itemid, propid, pguid) = (!inner).GetGuidProperty(itemid, propid, ref pguid)
+                member h.SetGuidProperty(itemid, propid, rguid) = (!inner).SetGuidProperty(itemid, propid, ref rguid)
+                member h.GetProperty(itemid, propid, pvar) = 
+                    let propid:__VSHPROPID  = enum propid
+                    let next itemid propid = (!inner).GetProperty(itemid, int32 propid)
+                    let hr,var = impl2 getProperty next itemid propid
+                    pvar<-var
+                    hr
+                member h.SetProperty(itemid, propid, var) = (!inner).SetProperty(itemid, propid, var)
+                member h.GetNestedHierarchy(itemid, iidHierarchyNested, ppHierarchyNested, pitemidNested) = (!inner).GetNestedHierarchy(itemid,ref iidHierarchyNested, ref ppHierarchyNested, ref pitemidNested)
+                /// For project files, returns the fully qualified path to the file including the filename itself.
+                member h.GetCanonicalName(itemid, pbstrName) = 
+                    let next itemid = (!inner).GetCanonicalName(itemid)
+                    let hr,n = impl1 getCanonicalName next itemid
+                    pbstrName<-n
+                    hr                     
+                member h.ParseCanonicalName(pszName, pitemid) = (!inner).ParseCanonicalName(pszName, ref pitemid)
+                member h.Unused0() = (!inner).Unused0()
+                member h.AdviseHierarchyEvents(pEventSink, pdwCookie) = (!inner).AdviseHierarchyEvents(pEventSink, ref pdwCookie)
+                member h.UnadviseHierarchyEvents(dwCookie) = (!inner).UnadviseHierarchyEvents(dwCookie)
+                member h.Unused1() = (!inner).Unused1()
+                member h.Unused2() = (!inner).Unused2()
+                member h.Unused3() = (!inner).Unused3()
+                member h.Unused4() = (!inner).Unused4()
+             interface IDelegable<IVsHierarchy> with
+                member id.GetInner() = !inner
+                member id.SetInner(i) = inner := i
+                
+             interface IProvideProjectSite with
+                member x.GetProjectSite() = ((!inner) :?> IProvideProjectSite).GetProjectSite()
+
+             }       
+             
+        static member MakeTextManager() = 
+            {new IVsTextManager with
+                member tm.RegisterView(pView,pBuffer) = notimpl()
+                member tm.UnregisterView(pView) = notimpl()
+                member tm.EnumViews(pBuffer,ppEnum) = notimpl()
+                member tm.CreateSelectionAction(pBuffer,ppAction) = notimpl()
+                member tm.MapFilenameToLanguageSID(pszFileName,pguidLangSID) = notimpl()
+                member tm.GetRegisteredMarkerTypeID(pguidMarker,piMarkerTypeID) = notimpl()
+                member tm.GetMarkerTypeInterface(iMarkerTypeID, ppMarkerType) = notimpl()
+                member tm.GetMarkerTypeCount(piMarkerTypeCount) = notimpl()
+                member tm.GetActiveView(fMustHaveFocus,pBuffer,ppView) = notimpl()
+                member tm.GetUserPreferences(pViewPrefs, pFramePrefs, pLangPrefs, pColorPrefs) = notimpl()
+                member tm.SetUserPreferences(pViewPrefs,pFramePrefs,pLangPrefs,pColorPrefs) = notimpl()
+                member tm.SetFileChangeAdvise(pszFileName,fStart) = notimpl()
+                member tm.SuspendFileChangeAdvise(pszFileName,fSuspend) = notimpl()
+                member tm.NavigateToPosition(pBuffer,guidDocViewType,iPos,iLen) = notimpl()
+                member tm.NavigateToLineAndColumn(pBuffer,guidDocViewType,iStartRow,iStartIndex,iEndRow,iEndIndex) = notimpl()
+                member tm.GetBufferSccStatus(pBufData,pbNonEditable) = notimpl()
+                member tm.RegisterBuffer(pBuffer) = notimpl()
+                member tm.UnregisterBuffer(pBuffer) = notimpl()
+                member tm.EnumBuffers(ppEnum) = notimpl()
+                member tm.GetPerLanguagePreferences(pLangPrefs) = notimpl()
+                member tm.SetPerLanguagePreferences(pLangPrefs) = notimpl()
+                member tm.AttemptToCheckOutBufferFromScc(pBufData,pfCheckoutSucceeded) = notimpl()
+                member tm.GetShortcutManager(ppShortcutMgr) = notimpl()
+                member tm.RegisterIndependentView(pUnk,pBuffer) = notimpl()
+                member tm.UnregisterIndependentView(pUnk,pBuffer) = notimpl()
+                member tm.IgnoreNextFileChange(pBuffer) = notimpl()
+                member tm.AdjustFileChangeIgnoreCount(pBuffer,fIgnore) = notimpl()
+                member tm.GetBufferSccStatus2(pszFileName,pbNonEditable,piStatusFlags) = notimpl()
+                member tm.AttemptToCheckOutBufferFromScc2(pszFileName,pfCheckoutSucceeded,piStatusFlags) = notimpl()
+                member tm.EnumLanguageServices(ppEnum) = notimpl()
+                member tm.EnumIndependentViews(pBuffer,ppEnum) = notimpl()              
+            }
+            
+        static member DelegateTextManager(oldtm:IVsTextManager, ?getActiveView) = 
+            let inner = ref oldtm
+            {new IVsTextManager with
+                member tm.RegisterView(pView,pBuffer) = notimpl()
+                member tm.UnregisterView(pView) = notimpl()
+                member tm.EnumViews(pBuffer,ppEnum) = notimpl()
+                member tm.CreateSelectionAction(pBuffer,ppAction) = notimpl()
+                member tm.MapFilenameToLanguageSID(pszFileName,pguidLangSID) = notimpl()
+                member tm.GetRegisteredMarkerTypeID(pguidMarker,piMarkerTypeID) = notimpl()
+                member tm.GetMarkerTypeInterface(iMarkerTypeID, ppMarkerType) = notimpl()
+                member tm.GetMarkerTypeCount(piMarkerTypeCount) = notimpl()
+                member tm.GetActiveView(fMustHaveFocus,pBuffer,ppView) = 
+                    let next fMustHaveFocus pBuffer = (!inner).GetActiveView(fMustHaveFocus,pBuffer)
+                    let hr,v = impl2 getActiveView next fMustHaveFocus pBuffer
+                    ppView<-v
+                    hr   
+                member tm.GetUserPreferences(pViewPrefs, pFramePrefs, pLangPrefs, pColorPrefs) = notimpl()
+                member tm.SetUserPreferences(pViewPrefs,pFramePrefs,pLangPrefs,pColorPrefs) = notimpl()
+                member tm.SetFileChangeAdvise(pszFileName,fStart) = notimpl()
+                member tm.SuspendFileChangeAdvise(pszFileName,fSuspend) = notimpl()
+                member tm.NavigateToPosition(pBuffer,guidDocViewType,iPos,iLen) = notimpl()
+                member tm.NavigateToLineAndColumn(pBuffer,guidDocViewType,iStartRow,iStartIndex,iEndRow,iEndIndex) = notimpl()
+                member tm.GetBufferSccStatus(pBufData,pbNonEditable) = notimpl()
+                member tm.RegisterBuffer(pBuffer) = notimpl()
+                member tm.UnregisterBuffer(pBuffer) = notimpl()
+                member tm.EnumBuffers(ppEnum) = notimpl()
+                member tm.GetPerLanguagePreferences(pLangPrefs) = notimpl()
+                member tm.SetPerLanguagePreferences(pLangPrefs) = notimpl()
+                member tm.AttemptToCheckOutBufferFromScc(pBufData,pfCheckoutSucceeded) = notimpl()
+                member tm.GetShortcutManager(ppShortcutMgr) = notimpl()
+                member tm.RegisterIndependentView(pUnk,pBuffer) = notimpl()
+                member tm.UnregisterIndependentView(pUnk,pBuffer) = notimpl()
+                member tm.IgnoreNextFileChange(pBuffer) = notimpl()
+                member tm.AdjustFileChangeIgnoreCount(pBuffer,fIgnore) = notimpl()
+                member tm.GetBufferSccStatus2(pszFileName,pbNonEditable,piStatusFlags) = notimpl()
+                member tm.AttemptToCheckOutBufferFromScc2(pszFileName,pfCheckoutSucceeded,piStatusFlags) = notimpl()
+                member tm.EnumLanguageServices(ppEnum) = notimpl()
+                member tm.EnumIndependentViews(pBuffer,ppEnum) = notimpl()              
+             interface IDelegable<IVsTextManager> with
+                member id.GetInner() = !inner
+                member id.SetInner(i) = inner := i
+            }
+    let private getInner (o:'a) = 
+        let d = (box o):?>(IDelegable<'a>)
+        d.GetInner()
+        
+    let private setInner (o:'a) i = 
+        let d = (box o):?>(IDelegable<'a>)
+        d.SetInner(i)
+        
+
+    // IVsTextLayer ---------------------------------------------------------------------------------------------------------        
+    let createTextLayer() = 
+        let tl = Vs.DelegateTextLayer (Vs.MakeTextLayer())
+        let inner = getInner tl
+        let localLineIndexToBase (iLocalLine:int) (iLocalIndex:int) =
+            Some(ok,iLocalLine,iLocalIndex) // For now, just forward the values with no translation
+        let inner = Vs.DelegateTextLayer(inner, localLineIndexToBase=localLineIndexToBase)
+        setInner tl inner
+        tl
+        
+    // IVsTextView ---------------------------------------------------------------------------------------------------------        
+    let createTextView() : IVsTextView = Vs.DelegateTextView(Vs.MakeTextView())
+    let setFileText (filename:string) (tv:IVsTextView) (lines:string array) (recolorizeLines:int->int->unit) (getColorStateAtStartOfLine:int->int) = 
+        let filename = Internal.Utilities.FileSystem.Path.SafeGetFullPath(filename)
+        let inner = getInner tv
+        let lineCount = lines.Length
+        let getLineCount() = Some(ok, lines.Length)
+        // Line number is zero-relative.
+        let getLengthOfLine line = Some(ok, lines.[line].Length)
+        // It looks like VS has GetLineText taking zero-relative values.
+        // The actually cursor position is 1-relative though
+        let getLineText iStartLine iStartIndex iEndLine iEndIndex = 
+            let slice = [iStartLine..iEndLine] 
+                            |>List.map(fun i->(lines.[i].Substring(iStartIndex, iEndIndex-iStartIndex)))
+            Some(ok, System.String.Join("\r\n",Array.ofList slice))
+        let recolorizeLines (top:int) (bottom:int) = 
+            recolorizeLines top bottom
+            Some(ok)
+        let getColorStateAtStartOfLine (line:int) = 
+            Some(ok,getColorStateAtStartOfLine line)
+            
+        let vsBufferMoniker = Guid("978A8E17-4DF8-432A-9623-D530A26452BC")
+            
+        let getData (riidKey:Guid ref) =            
+            if !riidKey = vsBufferMoniker then Some(ok, box filename)
+            else None
+                        
+        let tl = Vs.DelegateTextLines(Vs.MakeTextLines(),
+                                            getLineCount=getLineCount,
+                                            getLengthOfLine=getLengthOfLine, 
+                                            getLineText=getLineText,
+                                            recolorizeLines=recolorizeLines,
+                                            getColorStateAtStartOfLine=getColorStateAtStartOfLine,
+                                            getData=getData
+                                            )
+                                                    
+        // Maybe overly simplistic: Make the whole file visible in one page
+        let getScrollInfo _iBar =
+            Some(ok,0,lineCount-1,lineCount-1,0)
+        let toplayer:IVsTextLayer = createTextLayer()
+        let getTopmostLayer() = Some(ok,toplayer)
+        let getBuffer() = Some(ok, tl)
+        let inner = Vs.DelegateTextView(inner, getBuffer=getBuffer, getScrollInfo=getScrollInfo, getTopmostLayer=getTopmostLayer)
+        setInner tv inner
+
+        
+// (The RDT is no longer used by the product, but leaving in VsMocks/Salsa in case we need it again in the future            
+    // IVsRunningDocumentTable ---------------------------------------------------------------------------------------------------------        
+    let createRdt() = 
+        let unadviseRunningDocTableEvents _ = Some(ok)
+        Vs.DelegateRunningDocumentTable (Vs.MakeRunningDocumentTable(),unadviseRunningDocTableEvents=unadviseRunningDocTableEvents)
+    let openDocumentInRdt rdt cookie filename (textview:IVsTextView) hier = 
+        let filename = System.IO.Path.GetFullPath(filename) 
+        let inner = getInner rdt
+        let _hr, textlines = textview.GetBuffer()
+        let getDocumentInfoResult = (Some(ok,0u,0u,0u,filename,hier,cookie,Marshal.GetIUnknownForObject(textlines)))
+        let refGetDocumentInfoResult = ref getDocumentInfoResult
+        let getDocumentInfo c =
+            if cookie = c then !refGetDocumentInfoResult
+            else None
+        let findAndLockDocumentResult = (Some(ok,hier,0u,Marshal.GetIUnknownForObject(textlines),0u))
+        let refFindAndLockDocumentResult = ref findAndLockDocumentResult
+        let findAndLockDocument _dwRDTLockType pszMkDocument = 
+            if pszMkDocument = filename then !refFindAndLockDocumentResult
+            else None
+        let inner = Vs.DelegateRunningDocumentTable(inner,getDocumentInfo=getDocumentInfo,findAndLockDocument=findAndLockDocument)
+        setInner rdt inner
+// )
+
+    let createLanguagePreferences() = null:>LanguagePreferences
+    
+    // IVsHierarchy ---------------------------------------------------------------------------------------------------------        
+    let createHier(projectSiteFactory) =  
+        let getProperty _id _prop = Some(VSConstants.E_FAIL,null)
+        let hier = Vs.DelegateHierarchy(Vs.MakeHierarchy(projectSiteFactory), getProperty=getProperty)
+        hier
+    let setHierRoot hier projectdir projectname = 
+        let guid = System.Guid.NewGuid().ToString()
+        let inner = getInner hier
+        let getCanonicalName itemid = 
+            if itemid = VSConstants.VSITEMID_ROOT then Some(ok,projectdir)
+            else None
+        let getProperty id prop =
+            if id = VSConstants.VSITEMID_ROOT then
+                match prop with
+                | __VSHPROPID.VSHPROPID_Name->Some(ok, box projectname)
+                | __VSHPROPID.VSHPROPID_ProjectDir->Some(ok, box projectdir)
+                | __VSHPROPID.VSHPROPID_OwnerKey->Some(ok, box guid)
+                | _ -> Some(fail,null)
+            else None
+        let inner = Vs.DelegateHierarchy(inner, getCanonicalName=getCanonicalName,getProperty=getProperty)
+        setInner hier inner
+    let rec getLastSiblingId (hier:IVsHierarchy) (last:uint32) =
+        let hr,next = hier.GetProperty(last, int32 __VSHPROPID.VSHPROPID_NextSibling)
+        if hr = VSConstants.S_OK then 
+            let nid:int32 = downcast next
+            getLastSiblingId hier (uint32 nid)
+        else last
+        
+    let addChild (hier:IVsHierarchy) parentItemId childItemId filename =
+        let hr, child = hier.GetProperty(parentItemId, int32 __VSHPROPID.VSHPROPID_FirstChild)
+        let inner = getInner hier
+        let cid = (int32)childItemId // VS is confused about whether it wants item IDs to be signed or unsigned.
+        let getCanonicalName id = 
+            if id = childItemId then Some(ok,filename)
+            else None            
+        if hr = VSConstants.S_OK then
+            // There's already a first child, add as a sibling
+            let childi32:int32 = downcast child
+            let lastSiblingId = getLastSiblingId hier (uint32 childi32)
+            let getProperty id prop = 
+                if id = lastSiblingId then 
+                    match prop with
+                    | __VSHPROPID.VSHPROPID_NextSibling -> Some(ok, box cid)
+                    | _ -> None
+                else if id = childItemId then
+                    match prop with
+                    | __VSHPROPID.VSHPROPID_Name-> Some(ok, box filename)
+                    | __VSHPROPID.VSHPROPID_NextSibling -> Some(fail, null)
+                    | _ -> None
+                else None
+            let inner = Vs.DelegateHierarchy(inner, getProperty=getProperty, getCanonicalName=getCanonicalName)
+            setInner hier inner
+        else 
+            let getProperty id prop =
+                if id = parentItemId then 
+                    match prop with 
+                    | __VSHPROPID.VSHPROPID_FirstChild -> Some(ok, box cid)
+                    | _ -> None
+                else if id = childItemId then
+                    match prop with
+                    | __VSHPROPID.VSHPROPID_Name-> Some(ok, box filename)
+                    | __VSHPROPID.VSHPROPID_NextSibling -> Some(fail, null)
+                    | _ -> None
+                else None
+            let inner = Vs.DelegateHierarchy(inner, getProperty=getProperty, getCanonicalName=getCanonicalName)
+            setInner hier inner
+    
+    let addRootChild hier childItemId filename = 
+        addChild hier VSConstants.VSITEMID_ROOT childItemId filename 
+        
+    // IVsTextManager ---------------------------------------------------------------------------------------------------------        
+    let createTextManager() = Vs.DelegateTextManager (Vs.MakeTextManager())
+    let setActiveView tm (view:IVsTextView) =
+        let inner = getInner tm
+        let getActiveView (_mustHaveFocus:int) (_buffer:IVsTextBuffer) = Some(ok,view)
+        let inner = Vs.DelegateTextManager(inner, getActiveView=getActiveView)
+        setInner tm inner
+        
+    type MuxLogger() =
+        let mutable innerLoggers = []
+        let mutable iEventSource = null
+        member x.Add(logger : ILogger) = 
+            innerLoggers <- logger :: innerLoggers
+            if iEventSource <> null then
+                logger.Initialize(iEventSource)  // hacky, but works well enough for unit tests, unfortunately 'register' calls can come after 'initialize' call
+        interface ILogger with
+            member x.Initialize(eventSource) =
+                innerLoggers |> List.iter (fun l -> l.Initialize(eventSource))
+                iEventSource <- eventSource
+            member x.Shutdown() =
+                innerLoggers |> List.iter (fun l -> l.Shutdown())
+                iEventSource <- null
+            member x.Parameters with get() = match innerLoggers with [] -> "" | h::t -> h.Parameters
+                                and set(s) = innerLoggers |> List.iter (fun l -> l.Parameters <- s)
+            member x.Verbosity with get() = match innerLoggers with [] -> LoggerVerbosity.Normal | h::t -> h.Verbosity
+                               and set(s) = innerLoggers |> List.iter (fun l -> l.Verbosity <- s)
+
+    /////////////////////////////////
+    // mocks
+    let err(line) : int = 
+        printfn "err() called on line %s with %s" line System.Environment.StackTrace 
+        failwith "not implemented"
+    let nothing() = 0
+            
+    let vsShell() =
+        let dict = new Dictionary<int,Object>()
+        let shell = { new IVsShell with
+            member this.AdviseBroadcastMessages(sink, cookie) = err(__LINE__)
+            member this.AdviseShellPropertyChanges(sink, cookie) = err(__LINE__)
+            member this.GetPackageEnum e = err(__LINE__)
+            member this.GetProperty (propId : int, result : byref<Object>) = 
+                let value = ref (null : Object)
+                let ok = dict.TryGetValue(propId, value)
+                if ok then
+                    result <- !value
+                    0
+                else
+                    result <- null
+                    1
+            member this.IsPackageInstalled (guid, inst) = err(__LINE__)
+            member this.IsPackageLoaded (guid, pack) = err(__LINE__)
+            member this.LoadPackage (guid, pack) = err(__LINE__)
+            member this.LoadPackageString (guid, id, str) = err(__LINE__)
+            member this.LoadUILibrary(guid, flags, lib) = err(__LINE__)
+            member this.SetProperty (propId : int, x : Object) =
+                dict.Add(propId, x)
+                0
+            member this.UnadviseBroadcastMessages cookie = err(__LINE__)
+            member this.UnadviseShellPropertyChanges cookie = err(__LINE__)
+            }
+        shell.SetProperty(int __VSSPROPID.VSSPROPID_IsInCommandLineMode, box false) |> ignore
+        shell.SetProperty(int __VSSPROPID.VSSPROPID_InstallDirectory, box "") |> ignore
+        shell
+        
+
+    let vsUIHierarchyWindow =
+        { new IVsUIHierarchyWindow with
+            member this.Init(  pUIH,   grfUIHWF,    ppunkOut) = err(__LINE__)
+            member this.ExpandItem(  pUIH,   itemid,   expf) =
+                0
+            member this.AddUIHierarchy(  pUIH,   grfAddOptions) = err(__LINE__)
+            member this.RemoveUIHierarchy(  pUIH) = err(__LINE__)
+            member this.SetWindowHelpTopic(  lpszHelpFile,   dwContext) = err(__LINE__)
+            member this.GetItemState(  pHier,   itemid,   dwStateMask,    pdwState) = 
+                0
+            member this.FindCommonSelectedHierarchy(  grfOpt,    lppCommonUIH) = err(__LINE__)
+            member this.SetCursor(  hNewCursor,    phOldCursor) = err(__LINE__)
+            member this.GetCurrentSelection(  ppHier,    pitemid,    ppMIS) = err(__LINE__)
+            }
+    
+    let vsWindowFrame =
+        { new IVsWindowFrame with
+            member this.Show() = err(__LINE__)
+            member this.Hide() = err(__LINE__)
+            member this.IsVisible() = err(__LINE__)
+            member this.ShowNoActivate() = err(__LINE__)
+            member this.CloseFrame(  grfSaveOptions) = err(__LINE__)
+            member this.SetFramePos(  dwSFP,    rguidRelativeTo,   x,   y,   cx,   cy) = err(__LINE__)
+            member this.GetFramePos(  pdwSFP,   pguidRelativeTo,   px,   py,   pcx,   pcy) = err(__LINE__)
+            member this.GetProperty(  propid,    pvar : byref<obj>) = 
+                pvar <- vsUIHierarchyWindow
+                0
+            member this.SetProperty(  propid,   var) = err(__LINE__)
+            member this.GetGuidProperty(  propid,   pguid) = err(__LINE__)
+            member this.SetGuidProperty(  propid,    rguid) = err(__LINE__)
+            member this.QueryViewInterface(   riid,   ppv) = err(__LINE__)
+            member this.IsOnScreen(   pfOnScreen) = err(__LINE__)
+            }
+
+    let mutable vsUIShellShowMessageBoxResult = None
+    
+    let vsUIShell =
+        { new IVsUIShell with
+            member this.GetToolWindowEnum(   ppenum) = err(__LINE__)
+            member this.GetDocumentWindowEnum(   ppenum) =
+                // cons up a fake empty enumerator (e.g. don't really support this)
+                ppenum <- { new IEnumWindowFrames with
+                                member this.Next(celt, rgelt, pceltFetched) = pceltFetched <- 0u; 0
+                                member this.Skip(celt) = 0
+                                member this.Reset() = 0
+                                member this.Clone(ppenum) = ppenum <- this; 0 }
+                0
+            member this.FindToolWindow(  grfFTW,    rPersistenceSlot,    ppWindowFrame: byref<IVsWindowFrame> ) =
+                ppWindowFrame <- vsWindowFrame
+                0
+            member this.CreateToolWindow(  grfCTW,   dwToolWindowId,   punkTool,    rclsidTool,    rPersistenceSlot,    rAutoActivate,   psp,   pszCaption,   pfDefaultPosition,    ppWindowFrame) = err(__LINE__)
+            member this.CreateDocumentWindow(  grfCDW,   pszMkDocument,   pUIH,   itemid,   punkDocView,   punkDocData,    rEditorType,   pszPhysicalView,    rCmdUI,   psp,   pszOwnerCaption,   pszEditorCaption,   pfDefaultPosition,    ppWindowFrame) = err(__LINE__)
+            member this.SetErrorInfo(  hr,   pszDescription,   dwReserved,   pszHelpKeyword,   pszSource) = err(__LINE__)
+            member this.ReportErrorInfo(  hr) = err(__LINE__)
+            member this.GetDialogOwnerHwnd(  phwnd) = err(__LINE__)
+            member this.EnableModeless(  fEnable) = err(__LINE__)
+            member this.SaveDocDataToFile(  grfSave,   pPersistFile,   pszUntitledPath,    pbstrDocumentNew,    pfCanceled) = err(__LINE__)
+            member this.SetupToolbar(  hwnd,   ptwt,    pptwth) = err(__LINE__)
+            member this.SetForegroundWindow() = err(__LINE__)
+            member this.TranslateAcceleratorAsACmd(  pMsg) = err(__LINE__)
+            member this.UpdateCommandUI(  fImmediateUpdate) = err(__LINE__)
+            member this.UpdateDocDataIsDirtyFeedback(  docCookie,   fDirty) = err(__LINE__)
+            member this.RefreshPropertyBrowser(  dispid) = err(__LINE__)
+            member this.SetWaitCursor() = err(__LINE__)
+            member this.PostExecCommand(   pCmdGroup,   nCmdID,   nCmdexecopt,    pvaIn) = err(__LINE__)
+            member this.ShowContextMenu(  dwCompRole,    rclsidActive,   nMenuId,   pos,   pCmdTrgtActive) = err(__LINE__)
+            member this.ShowMessageBox(  dwCompRole,    rclsidComp,   pszTitle,   pszText,   pszHelpFile,   dwHelpContextID,   msgbtn,   msgdefbtn,   msgicon,   fSysAlert,    pnResult) = 
+                match vsUIShellShowMessageBoxResult with
+                | None -> err(__LINE__)
+                | Some(result) -> pnResult <- result; VSConstants.S_OK 
+            member this.SetMRUComboText(   pCmdGroup,   dwCmdID,   lpszText,   fAddToList) = err(__LINE__)
+            member this.SetToolbarVisibleInFullScreen(  pCmdGroup,   dwToolbarId,   fVisibleInFullScreen) = err(__LINE__)
+            member this.FindToolWindowEx(  grfFTW,    rPersistenceSlot,   dwToolWinId,    ppWindowFrame : byref<IVsWindowFrame> ) = err(__LINE__)
+            member this.GetAppName(   pbstrAppName) = err(__LINE__)
+            member this.GetVSSysColor(  dwSysColIndex,    pdwRGBval) = err(__LINE__)
+            member this.SetMRUComboTextW(  pCmdGroup,   dwCmdID,   pwszText,   fAddToList) = err(__LINE__)
+            member this.PostSetFocusMenuCommand(   pCmdGroup,   nCmdID) = err(__LINE__)
+            member this.GetCurrentBFNavigationItem(   ppWindowFrame,    pbstrData,    ppunk) = err(__LINE__)
+            member this.AddNewBFNavigationItem(  pWindowFrame,   bstrData,   punk,   fReplaceCurrent) = err(__LINE__)
+            member this.OnModeChange(  dbgmodeNew) = err(__LINE__)
+            member this.GetErrorInfo(   pbstrErrText) = err(__LINE__)
+            member this.GetOpenFileNameViaDlg(  pOpenFileName) = err(__LINE__)
+            member this.GetSaveFileNameViaDlg(  pSaveFileName) = err(__LINE__)
+            member this.GetDirectoryViaBrowseDlg(  pBrowse) = err(__LINE__)
+            member this.CenterDialogOnWindow(  hwndDialog,   hwndParent) = err(__LINE__)
+            member this.GetPreviousBFNavigationItem(   ppWindowFrame,    pbstrData,    ppunk) = err(__LINE__)
+            member this.GetNextBFNavigationItem(   ppWindowFrame,    pbstrData,    ppunk) = err(__LINE__)
+            member this.GetURLViaDlg(  pszDlgTitle,   pszStaticLabel,   pszHelpTopic,    pbstrURL) = err(__LINE__)
+            member this.RemoveAdjacentBFNavigationItem(  rdDir) = err(__LINE__)
+            member this.RemoveCurrentNavigationDupes(  rdDir) = err(__LINE__)
+            }
+
+    // peekhole to IVsTrackProjectDocuments2 - allows to receive notifications about removed files
+    type public IVsTrackProjectDocuments2Listener = 
+        abstract member OnAfterRemoveFiles : IEvent<IVsProject * int * string[] * VSREMOVEFILEFLAGS[]>
+
+
+    let vsTrackProjectDocuments2 = 
+        let onAfterRemoveFiles = Event<_>()
+        let track = { 
+            new IVsTrackProjectDocuments2 with            
+                member this.BeginBatch() = err(__LINE__)
+                member this.EndBatch() = err(__LINE__)
+                member this.Flush() = err(__LINE__)
+                member this.OnQueryAddFiles(pProject, cFiles, rgpszMkDocuments, rgFlags, pSummaryResult, rgResults) =
+                    pSummaryResult.[0] <- VSQUERYADDFILERESULTS.VSQUERYADDFILERESULTS_AddOK
+                    0
+                member this.OnAfterAddFilesEx( pProject,  cFiles,  rgpszMkDocuments,  rgFlags) = 
+                    let proj = (pProject :?> FSharpProjectNode) :> IVsTrackProjectDocumentsEvents2
+                    proj.OnAfterAddFilesEx(1, cFiles, [|pProject|], Array.create cFiles 0, rgpszMkDocuments, rgFlags)
+                member this.OnAfterAddFiles( pProject,  cFiles,  rgpszMkDocuments) = nothing()
+                member this.OnAfterAddDirectoriesEx( pProject,  cDirectories,  rgpszMkDocuments,  rgFlags) = err(__LINE__)
+                member this.OnAfterAddDirectories( pProject,  cDirectories,  rgpszMkDocuments) = err(__LINE__)
+                member this.OnAfterRemoveFiles(  pProject, cFiles, rgpszMkDocuments,  rgFlags) = 
+                    onAfterRemoveFiles.Trigger(pProject, cFiles, rgpszMkDocuments, rgFlags)
+                    0
+                member this.OnAfterRemoveDirectories(  pProject, cDirectories, rgpszMkDocuments,  rgFlags) = err(__LINE__)
+                member this.OnQueryRenameFiles(  pProject, cFiles, rgszMkOldNames, rgszMkNewNames,  rgFlags,  pSummaryResult,  rgResults) = err(__LINE__)
+                member this.OnQueryRenameFile(  pProject, pszMkOldName, pszMkNewName,  flags,  outpfRenameCanContinue) =
+                    outpfRenameCanContinue <- 1
+                    0
+                member this.OnAfterRenameFiles(  pProject, cFiles, rgszMkOldNames, rgszMkNewNames,  rgFlags) = err(__LINE__)
+                member this.OnAfterRenameFile(  pProject, pszMkOldName, pszMkNewName,  flags) =
+                    0
+                member this.OnQueryRenameDirectories(  pProject, cDirs, rgszMkOldNames, rgszMkNewNames,  rgFlags,  pSummaryResult,  rgResults) = err(__LINE__)
+                member this.OnAfterRenameDirectories(  pProject, cDirs, rgszMkOldNames, rgszMkNewNames,  rgFlags) = err(__LINE__)
+                member this.AdviseTrackProjectDocumentsEvents( pEventSink,  pdwCookie) = nothing()
+                member this.UnadviseTrackProjectDocumentsEvents( dwCookie) = nothing()
+                member this.OnQueryAddDirectories(  pProject, cDirectories, rgpszMkDocuments,  rgFlags,  pSummaryResult,  rgResults) = err(__LINE__)
+                member this.OnQueryRemoveFiles(  pProject, cFiles, rgpszMkDocuments,  rgFlags,  pSummaryResult,  rgResults) = 
+                    if rgResults <> null then
+                        for i = 0 to rgResults.Length-1 do
+                            rgResults.[i] <- VSQUERYREMOVEFILERESULTS.VSQUERYREMOVEFILERESULTS_RemoveOK
+                    pSummaryResult.[0] <- VSQUERYREMOVEFILERESULTS.VSQUERYREMOVEFILERESULTS_RemoveOK
+                    0
+                member this.OnQueryRemoveDirectories(  pProject, cDirectories, rgpszMkDocuments,  rgFlags,  pSummaryResult,  rgResults) = err(__LINE__)
+                member this.OnAfterSccStatusChanged(  pProject, cFiles, rgpszMkDocuments,  rgdwSccStatus) = err(__LINE__)
+
+            interface IVsTrackProjectDocuments2Listener with
+                member this.OnAfterRemoveFiles = onAfterRemoveFiles.Publish
+            }
+        track 
+    
+    let vsTaskList() = 
+            { new IVsTaskList with
+            member this.RegisterTaskProvider( pProvider, pdwProviderCookie : byref<uint32>) = 
+                pdwProviderCookie <- 0u
+                0
+            member this.UnregisterTaskProvider( dwProviderCookie) =
+                0
+            member this.RefreshTasks( dwProviderCookie) = 
+                0
+            member this.EnumTaskItems( ppenum : byref<IVsEnumTaskItems> ) = err(__LINE__)
+            member this.AutoFilter( cat) = err(__LINE__)
+            member this.UpdateProviderInfo( dwProviderCookie) = err(__LINE__)
+            member this.SetSilentOutputMode( fSilent) = err(__LINE__)
+            member this.DumpOutput( dwReserved,  cat,  pstmOutput,  pfOutputWritten : byref<int> ) = err(__LINE__)
+            member this.RegisterCustomCategory( guidCat : byref<Guid>,  dwSortOrder,  pCat) = err(__LINE__)
+            member this.UnregisterCustomCategory( catAssigned) = err(__LINE__)
+            member this.AutoFilter2( guidCustomView : byref<Guid>) = err(__LINE__)
+            }
+    let vsMonitorSelection = 
+        { new IVsMonitorSelection with
+        member this.GetCurrentSelection(ppHier,  pitemid,  ppMIS, ppSC) =
+            0
+        member this.AdviseSelectionEvents( pSink,  pdwCookie) = 
+            0
+        member this.UnadviseSelectionEvents( dwCookie) = err(__LINE__)
+        member this.GetCurrentElementValue( elementid,  pvarValue) = err(__LINE__)
+        member this.GetCmdUIContextCookie( rguidCmdUI,  pdwCmdUICookie) = err(__LINE__)
+        member this.IsCmdUIContextActive( dwCmdUICookie,  pfActive) = err(__LINE__)
+        member this.SetCmdUIContext( dwCmdUICookie,  fActive) = err(__LINE__)
+        }
+        
+    let vsFileChangeManager =
+        { new IVsFileChangeEx with
+            member this.AdviseDirChange(pszDir, fWatchSubDir, pFCE, pvsCookie) = err(__LINE__)
+            member this.AdviseFileChange(pszMkDocument, grfFilter, pFCE, pvsCookie) = nothing()
+            member this.IgnoreFile(vscookie, pszMkDocument, fIgnore) = 
+                0
+            member this.SyncFile(pszMkDocument) = err(__LINE__)
+            member this.UnadviseDirChange(vscookie) = err(__LINE__)
+            member this.UnadviseFileChange(vscookie) = nothing()
+        }
+
+#if NOT_YET_NEEDED
+    let vsExtensibility3 =
+        { new IVsExtensibility3 with
+            member this.GetProperties(pParent, pdispPropObj, ppProperties) = err(__LINE__)
+            member this.RunWizardFile(bstrWizFilename,  hwndOwner,  vContextParams,  pResult) = err(__LINE__)
+            member this.EnterAutomationFunction() = err(__LINE__)
+            member this.ExitAutomationFunction() = err(__LINE__)
+            member this.IsInAutomationFunction(pfInAutoFunc) = err(__LINE__)
+            member this.GetUserControl( fUserControl) = err(__LINE__)
+            member this.SetUserControl( fUserControl) = err(__LINE__)
+            member this.SetUserControlUnlatched( fUserControl) = err(__LINE__)
+            member this.LockServer( vb) = err(__LINE__)
+            member this.GetLockCount( pCount) = err(__LINE__)
+            member this.TestForShutdown( fShutdown) = err(__LINE__)
+            member this.GetGlobalsObject( extractFrom,  ppGlobals) = err(__LINE__)
+            member this.GetConfigMgr( pIVsProject,  itemid,  ppCfgMgr) = err(__LINE__)
+            member this.FireMacroReset() = err(__LINE__)
+            member this.GetDocumentFromDocCookie( lDocCookie,  ppDoc) = err(__LINE__)
+            member this.IsMethodDisabled( pGUID,  dispid) = err(__LINE__)
+            member this. SetSuppressUI( In) = err(__LINE__)
+            member this.GetSuppressUI( pOut) = err(__LINE__)
+            member this.FireProjectsEvent_ItemAdded( project) = err(__LINE__)
+            member this.FireProjectsEvent_ItemRemoved( project) = err(__LINE__)
+            member this.FireProjectsEvent_ItemRenamed( project,  oldName) = err(__LINE__)
+            member this.FireProjectItemsEvent_ItemAdded( projectItem) = err(__LINE__)
+            member this.FireProjectItemsEvent_ItemRemoved( projectItem) = err(__LINE__)
+            member this.FireProjectItemsEvent_ItemRenamed( projectItem,  oldName) = err(__LINE__)
+            member this.IsFireCodeModelEventNeeded( vbNeeded) = err(__LINE__)
+            member this.RunWizardFileEx( bstrWizFilename,  hwndOwner,  vContextParams,  vCustomParams,  pResult) = err(__LINE__)
+            member this.FireCodeModelEvent3( dispid,  pParent,  pElement,  changeKind) = err(__LINE__)
+        }
+#endif
+
+    let vsSolution =
+        { new IVsSolution with
+            member x.GetProjectEnum(grfEnumFlags, rguidEnumOnlyThisType, ppenum) = err(__LINE__)
+            member x.CreateProject(rguidProjectType, lpszMoniker, lpszLocation, lpszName, grfCreateFlags, iidProject,ppProject) = err(__LINE__)
+            member x.GenerateUniqueProjectName(lpszRoot,  outpbstrProjectName) = err(__LINE__)
+            member x.GetProjectOfGuid(rguidProjectID,  outppHierarchy) = err(__LINE__)
+            member x.GetGuidOfProject(pHierarchy,pguidProjectID) = err(__LINE__)
+            member x.GetSolutionInfo( outpbstrSolutionDirectory,  outpbstrSolutionFile,  outpbstrUserOptsFile) = 
+                outpbstrSolutionDirectory <- ""
+                outpbstrSolutionFile <- ""
+                outpbstrUserOptsFile <- ""
+                0
+            member x.AdviseSolutionEvents( pSink,  outpdwCookie) = err(__LINE__)
+            member x.UnadviseSolutionEvents(dwCookie) = err(__LINE__)
+            member x.SaveSolutionElement(grfSaveOpts, pHier, docCookie) = err(__LINE__)
+            member x.CloseSolutionElement(grfCloseOpts, pHier, docCookie) = err(__LINE__)
+            member x.GetProjectOfProjref(pszProjref,  outppHierarchy,  outpbstrUpdatedProjref,   puprUpdateReason) = err(__LINE__)
+            member x.GetProjrefOfProject(pHierarchy,  outpbstrProjref) = err(__LINE__)
+            member x.GetProjectInfoOfProjref(pszProjref, propid, pvar) = err(__LINE__)
+            member x.AddVirtualProject(pHierarchy, grfAddVPFlags) = err(__LINE__)
+            member x.GetItemOfProjref(pszProjref,  outppHierarchy,  outpitemid,  outpbstrUpdatedProjref,   puprUpdateReason) = err(__LINE__)
+            member x.GetProjrefOfItem(pHierarchy, itemid,  outpbstrProjref) = err(__LINE__)
+            member x.GetItemInfoOfProjref(pszProjref, propid, pvar) = err(__LINE__)
+            member x.GetProjectOfUniqueName(pszUniqueName,  outppHierarchy) = err(__LINE__)
+            member x.GetUniqueNameOfProject(pHierarchy,  outpbstrUniqueName) = err(__LINE__)
+            member x.GetProperty(propid, pvar) = err(__LINE__)
+            member x.SetProperty(propid,  var) = err(__LINE__)
+            member x.OpenSolutionFile(grfOpenOpts, pszFilename) = err(__LINE__)
+            member x.QueryEditSolutionFile( outpdwEditResult) = err(__LINE__)
+            member x.CreateSolution(lpszLocation, lpszName, grfCreateFlags) = err(__LINE__)
+            member x.GetProjectFactory(dwReserved, pguidProjectType, pszMkProject, ppProjectFactory) = err(__LINE__)
+            member x.GetProjectTypeGuid(dwReserved, pszMkProject,pguidProjectType) = err(__LINE__)
+            member x.OpenSolutionViaDlg(pszStartDirectory, fDefaultToAllProjectsFilter) = err(__LINE__)
+            member x.AddVirtualProjectEx(pHierarchy, grfAddVPFlags, rguidProjectID) = err(__LINE__)
+            member x.QueryRenameProject( pProject, pszMkOldName, pszMkNewName, dwReserved, pfRenameCanContinue) = err(__LINE__)
+            member x.OnAfterRenameProject( pProject, pszMkOldName, pszMkNewName, dwReserved) = err(__LINE__)
+            member x.RemoveVirtualProject(pHierarchy, grfRemoveVPFlags) = err(__LINE__)
+            member x.CreateNewProjectViaDlg(pszExpand, pszSelect, dwReserved) = err(__LINE__)
+            member x.GetVirtualProjectFlags(pHierarchy,  outpgrfAddVPFlags) = err(__LINE__)
+            member x.GenerateNextDefaultProjectName(pszBaseName, pszLocation,  outpbstrProjectName) = err(__LINE__)
+            member x.GetProjectFilesInSolution(grfGetOpts, cProjects, rgbstrProjectNames,  outpcProjectsFetched) = err(__LINE__)
+            member x.CanCreateNewProjectAtLocation(fCreateNewSolution, pszFullProjectFilePath, pfCanCreate) = err(__LINE__)
+        }
+
+    let dummyEmptyIEnumRunningDocuments =
+        {new IEnumRunningDocuments with
+            member ierd.Clone(ppenum) = err(__LINE__)
+            member ierd.Next(celt, rgelt, pceltFetched) = 
+                pceltFetched <- 0u
+                VSConstants.S_FALSE 
+            member ierd.Reset() =
+                0
+            member ierd.Skip(celt) = err(__LINE__)
+        }
+    let mutable vsRunningDocumentTableFindAndLockDocumentVsHierarchyMock = null : IVsHierarchy
+    let mutable vsRunningDocumentTableNextRenameDocumentCallThrows = false
+    
+    let vsRunningDocumentTable =
+        {new IVsRunningDocumentTable with
+            member rdt.RegisterAndLockDocument(grfRDTLockType, pszMkDocument, pHier, itemid, punkDocData, pdwCookie) = err(__LINE__)
+            member rdt.LockDocument(grfRDTLockType, dwCookie) = err(__LINE__)
+            member rdt.UnlockDocument(grfRDTLockType, dwCookie) = err(__LINE__)
+            member rdt.FindAndLockDocument(dwRDTLockType, pszMkDocument, ppHier, pitemid, ppunkDocData, pdwCookie) =
+                ppHier <- vsRunningDocumentTableFindAndLockDocumentVsHierarchyMock
+                0
+            member rdt.RenameDocument(pszMkDocumentOld, pszMkDocumentNew, pHier, itemidNew) =
+                if vsRunningDocumentTableNextRenameDocumentCallThrows then
+                    vsRunningDocumentTableNextRenameDocumentCallThrows <- false
+                    VSConstants.E_FAIL
+                else
+                    0
+            member rdt.AdviseRunningDocTableEvents(pSink, pdwCookie) = err(__LINE__)
+            member rdt.UnadviseRunningDocTableEvents(dwCookie) = err(__LINE__)
+            member rdt.GetDocumentInfo(docCookie, pgrfRDTFlags, pdwReadLocks, pdwEditLocks, pbstrMkDocument, ppHier, pitemid, ppunkDocData) = err(__LINE__)
+            member rdt.NotifyDocumentChanged(dwCookie, grfDocChanged) = err(__LINE__)
+            member rdt.NotifyOnAfterSave(dwCookie) = err(__LINE__)
+            member rdt.GetRunningDocumentsEnum(ppenum) = 
+                ppenum <- dummyEmptyIEnumRunningDocuments  // just lie, we don't mock enough of this
+                0
+            member rdt.SaveDocuments(grfSaveOpts, pHier, itemid, docCookie) = err(__LINE__)
+            member rdt.NotifyOnBeforeSave(dwCookie) = err(__LINE__)
+            member rdt.RegisterDocumentLockHolder(grfRDLH, dwCookie, pLockHolder, pdwLHCookie) = err(__LINE__)
+            member rdt.UnregisterDocumentLockHolder(dwLHCookie) = err(__LINE__)
+            member rdt.ModifyDocumentFlags(docCookie, grfFlags, fSet) = err(__LINE__) 
+        }
+
+    let MockVsBuildManagerAccessor() =
+        let muxLogger = ref Unchecked.defaultof<MuxLogger>
+        { new Microsoft.VisualStudio.Shell.Interop.IVsBuildManagerAccessor with
+            member x.RegisterLogger(submissionId, logger : obj) =
+                let iLogger = logger :?> ILogger 
+                (!muxLogger).Add(iLogger)
+                0
+            member x.ClaimUIThreadForBuild() = 0
+            member x.ReleaseUIThreadForBuild() = 0
+            member x.UnregisterLoggers(submissionId) = 0
+            member x.BeginDesignTimeBuild() =
+                muxLogger := new MuxLogger()
+                let buildParameters = new BuildParameters(Microsoft.Build.Evaluation.ProjectCollection.GlobalProjectCollection)
+                buildParameters.Loggers <- ([ ((!muxLogger) :> ILogger) ] :> System.Collections.Generic.IEnumerable<ILogger>)
+                buildParameters.HostServices <- Microsoft.Build.Evaluation.ProjectCollection.GlobalProjectCollection.HostServices
+                BuildManager.DefaultBuildManager.BeginBuild(buildParameters)
+                0
+            member x.EndDesignTimeBuild() =
+                BuildManager.DefaultBuildManager.EndBuild()
+                muxLogger := Unchecked.defaultof<MuxLogger>
+                0
+            member x.GetCurrentBatchBuildId(batchId) = 
+                batchId <- 0u // in the product, this would be non-zero if there are any in-progress builds, but we are not mocking solution manager, so we just always report no build in progress for unit tests
+                0
+            member x.GetSolutionConfiguration(rootProject: obj, xmlFragment: byref<string>) =
+                xmlFragment <- ""
+                0
+            member x.Escape(unescapedValue: string, escapedValue: byref<string>) = 0
+            member x.Unescape(escapedValue: string, unescapedValue: byref<string>) = 0
+        }
+
+    let vsTrackProjectRetargeting =
+        // This very simple mock will just do nothing but assert that the cookies
+        // match up for advise/unadvise
+        let _cookie = ref 0u
+        { new IVsTrackProjectRetargeting with
+            member this.OnSetTargetFramework(hier, currentFx, newFx, callback, reload) = 0
+            member this.AdviseTrackProjectRetargetingEvents(sink, cookie) =
+                _cookie := cookie
+                0
+            member this.UnadviseTrackProjectRetargetingEvents(cookie) =
+                Debug.Assert((!_cookie = cookie), sprintf "Invalid cookie for advise/unadvise!")
+                0
+            member this.AdviseTrackBatchRetargetingEvents(sink, cookie) = 0
+            member this.UnadviseTrackBatchRetargetingEvents(cookie) = 0    
+            member this.BeginRetargetingBatch() = 0
+            member this.BatchRetargetProject(hier, newFx, unloadProjectIfErrorOrCancel) = 0
+            member this.EndRetargetingBatch() = 0
+        }
+
+    let vsTargetFrameworkAssembliesN (n:uint32) =
+        { new IVsTargetFrameworkAssemblies with
+            member this.GetSupportedFrameworks(pTargetFrameworks) = notimpl()
+            member this.GetTargetFrameworkDescription(targetVersion, pszDescription) = notimpl()
+            member this.GetSystemAssemblies(targetVersion, pAssemblies) = notimpl()
+            member this.IsSystemAssembly(szAssemblyFile, pIsSystem, pTargetFrameworkVersion) = notimpl()
+            member this.GetRequiredTargetFrameworkVersion(szAssemblyFile, pTargetFrameworkVersion) = notimpl()
+            member this.GetRequiredTargetFrameworkVersionFromDependency(szAssemblyFile, pTargetFrameworkVersion) =
+                pTargetFrameworkVersion <- n
+                0
+        }
+
+    let vsTargetFrameworkAssemblies20 = vsTargetFrameworkAssembliesN 0x20000u
+    let vsTargetFrameworkAssemblies30 = vsTargetFrameworkAssembliesN 0x30000u
+    let vsTargetFrameworkAssemblies35 = vsTargetFrameworkAssembliesN 0x30005u
+    let vsTargetFrameworkAssemblies40 = vsTargetFrameworkAssembliesN 0x40000u
+    let vsTargetFrameworkAssemblies45 = vsTargetFrameworkAssembliesN 0x40005u
+    
+    let vsFrameworkMultiTargeting =
+        { new IVsFrameworkMultiTargeting with
+            member this.GetInstallableFrameworkForTargetFx(fx, res) =
+                let fn = new System.Runtime.Versioning.FrameworkName(fx)
+                if String.IsNullOrEmpty(fn.Profile) then
+                    res <- fn.FullName
+                else
+                    res <- fn.Profile
+                0
+            member this.IsReferenceableInTargetFx(a,b,c) = notimpl()
+            member this.GetTargetFramework(a,b,c) = notimpl()
+            member this.GetSupportedFrameworks(a) = notimpl()
+            member this.GetFrameworkAssemblies(a,b,c) = notimpl()
+            member this.CheckFrameworkCompatibility(a,b,c) = notimpl()
+            member this.ResolveAssemblyPath(a,b,c) = notimpl()
+            member this.GetDisplayNameForTargetFx(a,b) = notimpl()
+            member this.ResolveAssemblyPathsInTargetFx(a,b,c,d,e) = notimpl()
+        }
+        
+    // This provides a mock for LocalRegistry because for the multitargeting
+    // code we use this to create a text buffer
+        
+    let vsLocalRegistry f =
+        { new ILocalRegistry3 with
+            member this.CreateInstance(a,b,c,d,e) =
+                e <- Marshal.GetIUnknownForObject(f())
+                0
+            member this.GetTypeLibOfClsid(a,b) = notimpl()
+            member this.GetClassObjectOfClsid(a,b,c,d,e) = notimpl()
+            member this.GetLocalRegistryRoot(a) =
+                a <- ""
+                0
+            member this.CreateManagedInstance(a,b,c,d,e) = notimpl()
+            member this.GetClassObjectOfManagedClass(a,b,c,d,e) = notimpl()
+            
+          interface ILocalRegistry2 with
+            member this.CreateInstance(a,b,c,d,e) = notimpl()
+            member this.GetTypeLibOfClsid(a,b) = notimpl()
+            member this.GetClassObjectOfClsid(a,b,c,d,e) = notimpl()
+            member this.GetLocalRegistryRoot(a) =
+                a <- ""
+                0
+            
+          interface ILocalRegistry with
+            member this.CreateInstance(a,b,c,d,e) = notimpl()
+            member this.GetTypeLibOfClsid(a,b) = notimpl()
+            member this.GetClassObjectOfClsid(a,b,c,d,e) = notimpl()            
+        }
+
+    let MakeVsSolutionBuildManagerAndConfigChangeNotifier() =
+        let mkEventsStorage () = 
+            let listeners = Dictionary()
+            let id = ref 0u
+            let add l = 
+                let cookie = !id
+                listeners.Add(cookie, l)
+                id := !id + 1u
+                cookie
+            let remove v =
+                listeners.Remove(v) |> ignore
+            let enumerate() = listeners.Values
+            add, remove, enumerate
+
+        let add1, remove1, enumerate1 = mkEventsStorage()
+        let add2, remove2, _ = mkEventsStorage()
+        let configDict = new Dictionary<IVsHierarchy,string>()
+        let configChangeNotifier(h : IVsHierarchy, s : string) = 
+            if configDict.ContainsKey(h) then
+                configDict.[h] <- s
+            else
+                configDict.Add(h,s)
+            for (kvp : IVsUpdateSolutionEvents) in enumerate1() do
+                kvp.OnActiveProjectCfgChange(h) |> ignore 
+        let vsSolutionBuildManager = 
+            { new IVsSolutionBuildManager with
+                member x.DebugLaunch(grfLaunch) = err(__LINE__)
+                member x.StartSimpleUpdateSolutionConfiguration(dwFlags, dwDefQueryResults,   fSuppressUI) = err(__LINE__)
+                member x.AdviseUpdateSolutionEvents(  pIVsUpdateSolutionEvents,  outpdwCookie : byref<uint32> ) =
+                    outpdwCookie <- add1 pIVsUpdateSolutionEvents 
+                    0
+                member x.UnadviseUpdateSolutionEvents(dwCookie) =
+                    remove1 dwCookie
+                    0
+                member x.UpdateSolutionConfigurationIsActive(pfIsActive) = err(__LINE__)
+                member x.CanCancelUpdateSolutionConfiguration(pfCanCancel) = err(__LINE__)
+                member x.CancelUpdateSolutionConfiguration() = err(__LINE__)
+                member x.QueryDebugLaunch(grfLaunch, pfCanLaunch) = err(__LINE__)
+                member x.QueryBuildManagerBusy(pfBuildManagerBusy) = err(__LINE__)
+                member x.FindActiveProjectCfg( pvReserved1,  pvReserved2,   pIVsHierarchy_RequestedProject,   ppIVsProjectCfg_Active) =
+                    let mutable s = ""
+                    if not(configDict.TryGetValue(pIVsHierarchy_RequestedProject, &s)) then
+                        s <- ""
+                    let (_, vsCfgProvider : IVsCfgProvider) =(pIVsHierarchy_RequestedProject :?> IVsGetCfgProvider).GetCfgProvider()
+                    let cfgName = ConfigCanonicalName(s)
+                    let (_, cfg : IVsCfg) = (vsCfgProvider :?> IVsCfgProvider2).GetCfgOfName(cfgName.ConfigName, cfgName.Platform)
+                    ppIVsProjectCfg_Active.[0] <- downcast cfg 
+                    0                    
+                member x.get_IsDebug(pfIsDebug) = err(__LINE__)
+                member x.put_IsDebug(  fIsDebug) = err(__LINE__)
+                member x.get_CodePage( outpuiCodePage) = err(__LINE__)
+                member x.put_CodePage(uiCodePage) = err(__LINE__)
+                member x.StartSimpleUpdateProjectConfiguration(  pIVsHierarchyToBuild,   pIVsHierarchyDependent,   pszDependentConfigurationCanonicalName, dwFlags, dwDefQueryResults,   fSuppressUI) = err(__LINE__)
+                member x.get_StartupProject( ppHierarchy) = err(__LINE__)
+                member x.set_StartupProject(  pHierarchy) = err(__LINE__)
+                member x.GetProjectDependencies(  pHier, celt,   rgpHier, pcActual) = err(__LINE__)
+              interface IVsSolutionBuildManager2 with
+                member x.AdviseUpdateSolutionEvents(pIVsUpdateSolutionEvents, pdwCookie) =
+                    pdwCookie <- add2 pIVsUpdateSolutionEvents
+                    0
+                member x.CalculateProjectDependencies() = err(__LINE__)
+                member x.CanCancelUpdateSolutionConfiguration(_pfCanCancel) = err(__LINE__)
+                member x.CancelUpdateSolutionConfiguration() = err(__LINE__)
+                member x.DebugLaunch(_grfLaunch) = err(__LINE__)
+                member x.FindActiveProjectCfg(_pvReserved1, _pvReserved2, _pIVsHierarchy_RequestedProject, _ppIVsProjectCfg_Active) = err(__LINE__)
+                member x.GetProjectDependencies(_pHier, _celt, _rgpHier, _pcActual) = err(__LINE__)
+                member x.QueryBuildManagerBusy(_pfBuildManagerBusy) = err(__LINE__)
+                member x.QueryDebugLaunch(_grfLaunch, _pfCanLaunch) = err(__LINE__)
+                member x.QueryProjectDependency(_pHier, _pHierDependentOn, _pfIsDependentOn) = err(__LINE__)
+                member x.SaveDocumentsBeforeBuild(_pHier, _itemid, _docCookie) = err(__LINE__)
+                member x.StartSimpleUpdateProjectConfiguration(_pIVsHierarchyToBuild, _pIVsHierarchyDependent, _pszDependentConfigurationCanonicalName, _dwFlags, _dwDefQueryResults, _fSuppressUI) = err(__LINE__)
+                member x.StartSimpleUpdateSolutionConfiguration(_dwFlags, _dwDefQueryResults, _fSuppressUI) = err(__LINE__)
+                member x.StartUpdateProjectConfigurations(_cProjs, _rgpHierProjs, _dwFlags, _fSuppressUI) = err(__LINE__)
+                member x.StartUpdateSpecificProjectConfigurations(_cProjs, _rgpHier, _rgpcfg, _rgdwCleanFlags, _rgdwBuildFlags, _rgdwDeployFlags, _dwFlags, _fSuppressUI) = err(__LINE__)
+                member x.UnadviseUpdateSolutionEvents(dwCookie) = 
+                    remove2 dwCookie
+                    0
+                member x.UpdateSolutionConfigurationIsActive(_pfIsActive) = err(__LINE__)
+                member x.get_CodePage(_puiCodePage) = err(__LINE__)
+                member x.get_IsDebug(_pfIsDebug) = err(__LINE__)
+                member x.get_StartupProject(_ppHierarchy) = err(__LINE__)
+                member x.put_CodePage(_uiCodePage) = err(__LINE__)
+                member x.put_IsDebug(_fIsDebug) = err(__LINE__)
+                member x.set_StartupProject(_pHierarchy) = err(__LINE__)
+              interface IVsSolutionBuildManager3 with
+                member x.AdviseUpdateSolutionEvents3(a,b) =
+                    0
+                member x.AreProjectsUpToDate(a) = err(__LINE__)
+                member x.HasHierarchyChangedSinceLastDTEE () = err(__LINE__)
+                member x.QueryBuildManagerBusyEx(a) = err(__LINE__)
+                member x.UnadviseUpdateSolutionEvents3(a) =
+                    0
+        }
+        vsSolutionBuildManager, configChangeNotifier
+        
+    let MakeMockServiceProviderAndConfigChangeNotifierNoTargetFrameworkAssembliesService() = 
+        let vsSolutionBuildManager, configChangeNotifier = MakeVsSolutionBuildManagerAndConfigChangeNotifier()
+        let sp = new OleServiceProvider()
+
+        // allows to receive notifications about called methods of IVsTrackProjectDocuments2 interface
+        sp.AddService(typeof<IVsTrackProjectDocuments2Listener>, box vsTrackProjectDocuments2, false)
+
+        sp.AddService(typeof<SVsTrackProjectDocuments>, box vsTrackProjectDocuments2, false)
+        sp.AddService(typeof<SVsShell>, box (vsShell()), false)
+        sp.AddService(typeof<SVsUIShell>, box vsUIShell, false)
+        sp.AddService(typeof<SVsTaskList>, box(vsTaskList()), false) 
+        sp.AddService(typeof<SVsShellMonitorSelection>, box vsMonitorSelection, false) 
+        sp.AddService(typeof<SVsFileChangeEx>, box vsFileChangeManager, false)
+#if NOT_YET_NEEDED
+        sp.AddService(typeof<EnvDTE.IVsExtensibility>, box vsExtensibility3, false)
+#endif        
+        sp.AddService(typeof<SVsSolution>, box vsSolution, false)
+        sp.AddService(typeof<SVsSolutionBuildManager>, box vsSolutionBuildManager, false)
+        sp.AddService(typeof<SVsRunningDocumentTable>, box vsRunningDocumentTable, false)
+        sp.AddService(typeof<Microsoft.VisualStudio.Shell.Interop.SVsBuildManagerAccessor>, box (MockVsBuildManagerAccessor()), false)
+        sp.AddService(typeof<SVsTrackProjectRetargeting>, box vsTrackProjectRetargeting, false)
+        sp, configChangeNotifier
+
+    let MakeMockServiceProviderAndConfigChangeNotifier20() =
+        let sp, ccn = MakeMockServiceProviderAndConfigChangeNotifierNoTargetFrameworkAssembliesService()
+        sp.AddService(typeof<SVsTargetFrameworkAssemblies>, box vsTargetFrameworkAssemblies20, false)
+        sp.AddService(typeof<SVsFrameworkMultiTargeting>, box vsFrameworkMultiTargeting, false)
+        sp, ccn
+    let MakeMockServiceProviderAndConfigChangeNotifier30() =
+        let sp, ccn = MakeMockServiceProviderAndConfigChangeNotifierNoTargetFrameworkAssembliesService()
+        sp.AddService(typeof<SVsTargetFrameworkAssemblies>, box vsTargetFrameworkAssemblies30, false)
+        sp.AddService(typeof<SVsFrameworkMultiTargeting>, box vsFrameworkMultiTargeting, false)
+        sp, ccn
+    let MakeMockServiceProviderAndConfigChangeNotifier35() =
+        let sp, ccn = MakeMockServiceProviderAndConfigChangeNotifierNoTargetFrameworkAssembliesService()
+        sp.AddService(typeof<SVsTargetFrameworkAssemblies>, box vsTargetFrameworkAssemblies35, false)
+        sp.AddService(typeof<SVsFrameworkMultiTargeting>, box vsFrameworkMultiTargeting, false)
+        sp, ccn
+    let MakeMockServiceProviderAndConfigChangeNotifier40() =
+        let sp, ccn = MakeMockServiceProviderAndConfigChangeNotifierNoTargetFrameworkAssembliesService()
+        sp.AddService(typeof<SVsTargetFrameworkAssemblies>, box vsTargetFrameworkAssemblies40, false)
+        sp.AddService(typeof<SVsFrameworkMultiTargeting>, box vsFrameworkMultiTargeting, false)
+        sp, ccn
+    let MakeMockServiceProviderAndConfigChangeNotifier45() =
+        let sp, ccn = MakeMockServiceProviderAndConfigChangeNotifierNoTargetFrameworkAssembliesService()
+        sp.AddService(typeof<SVsTargetFrameworkAssemblies>, box vsTargetFrameworkAssemblies45, false)
+        sp.AddService(typeof<SVsFrameworkMultiTargeting>, box vsFrameworkMultiTargeting, false)
+        sp, ccn
+
+    // This is the mock thing that all tests, except the multitargeting tests call.
+    // By default, let it use the 4.0 assembly version.
+
+    let MakeMockServiceProviderAndConfigChangeNotifier() =
+        MakeMockServiceProviderAndConfigChangeNotifier40()
+
+    let mockServiceProvider = 
+        let sp, _ = MakeMockServiceProviderAndConfigChangeNotifier()
+        sp 
+            
+    let vsOutputWindowPane(owpe : string list ref) = 
+        { new IVsOutputWindowPane with
+            member this.Activate () = err(__LINE__)
+            member this.Clear () = owpe := []; 0
+            member this.FlushToTaskList () = VSConstants.S_OK
+            member this.GetName(pbstrPaneName) = err(__LINE__)
+            member this.Hide () = err(__LINE__)
+            member this.OutputString(pszOutputString) = owpe := pszOutputString :: !owpe ; 0
+            member this.OutputStringThreadSafe(pszOutputString) = owpe := pszOutputString :: !owpe ; 0
+            member this.OutputTaskItemString(pszOutputString, nPriority, nCategory, pszSubcategory, nBitmap, pszFilename, nLineNum, pszTaskItemText) = err(__LINE__)
+            member this.OutputTaskItemStringEx(pszOutputString, nPriority, nCategory, pszSubcategory, nBitmap, pszFilename, nLineNum, pszTaskItemText, pszLookupKwd) = err(__LINE__)
+            member this.SetName(pszPaneName) = err(__LINE__)
+        }            
+
+module internal VsActual = 
+    // Since the editor exports MEF components, we can use those components directly from unit tests without having to load too many heavy
+    // VS assemblies.  Use editor MEF components directly from the VS product.
+
+    open System.ComponentModel.Composition.Hosting
+    open System.ComponentModel.Composition.Primitives
+    open Microsoft.VisualStudio.Text
+
+    let vsInstallDir =
+        let key = @"SOFTWARE\Microsoft\VisualStudio\12.0"
+        let hklm = Microsoft.Win32.RegistryKey.OpenBaseKey(Microsoft.Win32.RegistryHive.LocalMachine, Microsoft.Win32.RegistryView.Registry32)
+        let rkey = hklm.OpenSubKey(key)
+        rkey.GetValue("InstallDir") :?> string
+
+    let CreateEditorCatalog() =
+        let root = vsInstallDir + @"\CommonExtensions\Microsoft\Editor"
+        let CreateAssemblyCatalog(root, file) =
+            let fullPath = System.IO.Path.Combine(root, file)
+            if System.IO.File.Exists(fullPath) then
+                new AssemblyCatalog(fullPath)
+            else
+                failwith("could not find " + fullPath)
+
+        // copy this private assembly next to unit tests, otherwise assembly loader cannot find it
+        let neededLocalAssem = vsInstallDir + @"\PrivateAssemblies\Microsoft.VisualStudio.Platform.VSEditor.Interop.dll"
+#if FX_ATLEAST_45
+        let curDir = System.IO.Path.GetDirectoryName((new System.Uri(System.Reflection.Assembly.Load("nunit.util").CodeBase)).LocalPath)
+#else
+        let curDir = System.IO.Path.GetDirectoryName((new System.Uri(System.Reflection.Assembly.GetExecutingAssembly().CodeBase)).LocalPath)
+#endif
+        let localCopy = System.IO.Path.Combine(curDir, System.IO.Path.GetFileName(neededLocalAssem))
+        System.IO.File.Copy(neededLocalAssem, localCopy, true)
+        
+        let list = new ResizeArray<ComposablePartCatalog>()
+        list.Add(CreateAssemblyCatalog(root, "Microsoft.VisualStudio.Platform.VSEditor.dll"))
+
+        // Must include this because several editor options are actually stored as exported information 
+        // on this DLL.  Including most importantly, the tab size information
+        list.Add(CreateAssemblyCatalog(root, "Microsoft.VisualStudio.Text.Logic.dll"))
+
+        // Include this DLL to get several more EditorOptions including WordWrapStyle
+        list.Add(CreateAssemblyCatalog(root, "Microsoft.VisualStudio.Text.UI.dll"))
+
+        // Include this DLL to get more EditorOptions values
+        list.Add(CreateAssemblyCatalog(root, "Microsoft.VisualStudio.Text.UI.Wpf.dll"))
+
+        // Include this DLL to get more undo operations
+        //list.Add(CreateAssemblyCatalog(root, "StandaloneUndo.dll"))
+        //list.Add(CreateAssemblyCatalog(root, "Microsoft.VisualStudio.Language.StandardClassification.dll"))
+
+        // list.Add(CreateAssemblyCatalog(root, "Microsoft.VisualStudio.Text.Internal.dll"))
+
+        new AggregateCatalog(list)
+
+    let exportProvider = new CompositionContainer(new AggregateCatalog(CreateEditorCatalog()), true, null)
+    let iTextBufferFactoryService = exportProvider.GetExportedValue<ITextBufferFactoryService>()
+    let createTextBuffer(text:string) = iTextBufferFactoryService .CreateTextBuffer(text, iTextBufferFactoryService .TextContentType)
\ No newline at end of file
diff --git a/vsintegration/src/Salsa/salsa.fs b/vsintegration/src/Salsa/salsa.fs
new file mode 100644
index 0000000..c1fc3ca
--- /dev/null
+++ b/vsintegration/src/Salsa/salsa.fs
@@ -0,0 +1,1714 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+(*
+    Simplified abstraction over visual studio.
+        Stand
+        Alone
+        Language 
+        Service
+        Acronym
+*)
+
+#nowarn "40" // let rec for recursive values
+namespace Salsa
+
+open Microsoft.VisualStudio.FSharp.LanguageService
+open Internal.Utilities.Debug
+open Microsoft.VisualStudio
+open Microsoft.VisualStudio.Shell.Interop
+open Microsoft.VisualStudio.FSharp.ProjectSystem
+open Microsoft.VisualStudio.FSharp.LanguageService
+open Microsoft.VisualStudio.TextManager.Interop
+open System
+open System.IO
+open System.Text
+open System.Collections.Generic 
+open System.Runtime.InteropServices
+open System.Threading
+open Implementation
+open Microsoft.FSharp.Compiler.AbstractIL.Diagnostics 
+open UnitTests.TestLib.Utils.FilesystemHelpers
+open Microsoft.Build.Framework
+open Microsoft.FSharp.Compiler.Range
+
+open Microsoft.Build.Evaluation
+
+module internal Salsa = 
+
+    exception MarkerNotFoundException of string
+
+    type HostCompile() =
+        let mutable capturedFlags = null
+        let mutable capturedSources = null
+        let mutable actuallyBuild = true
+        member th.CaptureSourcesAndFlagsWithoutBuildingForABit() =
+            actuallyBuild <- false
+            { new System.IDisposable with
+                    member this.Dispose() = actuallyBuild <- true }
+        member th.Results = capturedFlags, capturedSources
+        member th.Compile(compile:System.Converter<int,int>, flags:string[], sources:string[]) = 
+            use t = Trace.Call("MSBuild", "Compile", fun _ -> "Host compile invoke by Fsc task")
+            Trace.PrintLine("MSBuild", fun _ -> sprintf "flags=%A" flags)
+            capturedFlags <- flags 
+            capturedSources <- sources
+            if actuallyBuild then
+                compile.Invoke(0)
+            else
+                0         
+        interface ITaskHost
+        
+    type BuildResult = {
+        ExecutableOutput : string
+        BuildSucceeded : bool
+    }                     
+
+    /// Methods for dealing with MSBuild project files. 
+    module (*internal*) MSBuild =
+        let mutable private hasAttachedLogger = false
+        let mutable theAttachedLogger = null
+
+        /// Use the global build engine if it knows the path to MSBuild.exe
+        /// Otherwise, make a new engine and point it at well-known version of MSBuild
+        let GlobalEngine() = 
+            let engine = Utilities.InitializeMsBuildEngine(null)
+            if not hasAttachedLogger then 
+                hasAttachedLogger<-true
+                let logRegular = Trace.ShouldLog("MSBuild")
+                let logPerf = Trace.ShouldLog("MSBuildPerf")
+                if logRegular || logPerf then
+                    let l = if logRegular then 
+                                Trace.PrintLine("MSBuild", fun () -> "Detailed logging.")
+                                new Microsoft.Build.BuildEngine.ConsoleLogger(LoggerVerbosity.Detailed)
+                            else 
+                                Trace.PrintLine("MSBuild", fun () -> "Quiet logging.")
+                                new Microsoft.Build.BuildEngine.ConsoleLogger(LoggerVerbosity.Quiet)
+                    Trace.PrintLine("MSBuild", fun () -> "About to attach MSBuild console logger.")
+                    // For Dev10 build we pass the logger to the Build call on the project object.
+                    theAttachedLogger <- l
+                    Trace.PrintLine("MSBuild", fun () -> "Attached MSBuild console logger.")
+                    if logPerf then l.ApplyParameter("PERFORMANCESUMMARY", null)        
+            engine
+            
+        /// Set a global property on the given project.    
+        let SetGlobalProperty(project:Project, name, value) = 
+            let _ = project.SetGlobalProperty(name,value)
+            ()
+            
+        let hostObjectCachePerFilename = new System.Collections.Generic.Dictionary<_,_>()  // REVIEW: this will leak, but hopefully only a small amount (e.g. maybe about 1K per project, and thus maybe just a few megs total for all 2000 unit tests)
+
+        /// Get the MSBuild project for the given project file.
+        let GetProject (projectFileName:string, configuration:string, platform:string) = 
+            let project, justCreated, theHostObject =
+                try
+                    let projects = GlobalEngine().GetLoadedProjects(projectFileName) |> Seq.toList
+                    let project = match projects with
+                                  | [] -> null
+                                  | [x] -> x
+                                  | _ -> failwith "multiple projects found"
+                    match project with
+                    | null ->
+                        use t = Trace.Call("MSBuildPerf","Creating new project", fun _-> projectFileName)
+                        let project = GlobalEngine().LoadProject(projectFileName)
+                        // Set global properties.
+                        SetGlobalProperty(project,"BuildingInsideVisualStudio", "true")
+                        SetGlobalProperty(project,"Configuration", configuration)
+                        SetGlobalProperty(project,"Platform", platform)
+                        let prjColl = project.ProjectCollection
+                        let hostSvc = prjColl.HostServices
+                        let theHostObject = HostCompile()   
+                        hostSvc.RegisterHostObject(projectFileName, "CoreCompile", "Fsc", theHostObject)
+                        hostObjectCachePerFilename.[projectFileName] <- theHostObject
+                        project, true, theHostObject 
+                    | project-> 
+                        use t = Trace.Call("MSBuildPerf","Using existing project", fun _-> projectFileName)
+                        match hostObjectCachePerFilename.TryGetValue(projectFileName) with
+                        | true, theHostObject ->
+                            project, false, theHostObject
+                        | false, _ ->
+                            project, false, Unchecked.defaultof<_>  // this code path is hit when unit-testing the project system, which uses its own HostObject
+                with e->
+                    printfn "Failed in MSBuild GetProject getting '%s'.\n" projectFileName 
+                    raise e
+            project, justCreated, theHostObject
+
+        /// Interesting properties and item lists that from typical MSBuild project files.
+        type BuildFlags = {
+            flags:string list
+            sources:string list
+        }
+
+        let prop (project:Project) propertyName : string=
+            let p = project.GetPropertyValue(propertyName)
+            if p = null then "" else p
+
+        let items (project:Project) name =  
+            let l = project.GetItems(name) |> Seq.map (fun i -> i.EvaluatedInclude) |> Seq.toList
+            //use t = Trace.Call("MSBuild","items", fun _ -> sprintf " %s: %A" name l)
+            l
+
+
+        let oneItem (project:Project) name = 
+            match (items project name) with
+                  head::tail -> head
+                | _ -> ""
+
+        let splitProperty (project:Project) propertyName =
+            (prop project propertyName).Split([|';'|])|>Array.toList
+            
+        let boolProperty (project:Project) name =
+            let p = prop project name
+            true
+            
+        /// Build the given target on the given project. Return the name of the main output assembly.   
+        let Build(projectFileName, target, configuration, platform) : BuildResult =         
+            use t = Trace.Call("MSBuild","build", fun _-> sprintf " target=%s project=%s configruation=%s platform=%s" target projectFileName configuration platform)
+            let project,_,_ = GetProject(projectFileName, configuration, platform)
+            let projectInstance = project.CreateProjectInstance()
+            let buildResult = projectInstance.Build(target, Seq.append project.ProjectCollection.Loggers (if theAttachedLogger=null then [] else [theAttachedLogger]))
+            printfn "build succeeded? %A" buildResult
+            let mainassembly = 
+                try
+                    (projectInstance.GetItems("MainAssembly") |> Seq.head).EvaluatedInclude
+                with e ->
+                    ""  // TODO it seems like Dev10 "Clean" target does not produce this output, but this result is not consumed by those tests in an interesting way anyway
+            printfn "mainAssembly: %A" mainassembly 
+            {ExecutableOutput = mainassembly; BuildSucceeded = buildResult}
+            
+        /// Return the name of the main output assembly but don't build
+        let GetMainOutputAssembly(projectFileName, configuration, platform) : string =         
+            use t = Trace.Call("MSBuild","GetMainOutputAssembly", fun _-> sprintf " project=%s configruation=%s platform=%s" projectFileName configuration platform)
+            let project,_,_ = GetProject(projectFileName, configuration, platform)
+            let baseName = Path.GetFileNameWithoutExtension(projectFileName)+".exe"
+            let projectInstance = project.CreateProjectInstance()
+            let outdir : string = projectInstance.GetProperty("OutDir").EvaluatedValue
+            let mainassembly = Path.Combine(outdir,baseName)
+            printfn "mainAssembly: %A" mainassembly
+            mainassembly            
+        
+        let CreateFSharpManifestResourceName(projectFileName,configuration, platform) : (string * string) list=
+            let targetName = "CreateManifestResourceNames"
+            use t = Trace.Call("MSBuild", targetName, fun _-> sprintf " target=%s project=%s configruation=%s platform=%s" targetName projectFileName configuration platform)
+            let project,_,_ = GetProject(projectFileName, configuration, platform)
+            SetGlobalProperty(project, "CreateManifestResourceNamesDependsOn", "SplitResourcesByCulture")
+            let projectInstance = project.CreateProjectInstance()
+            let buildResult = projectInstance.Build(targetName, project.ProjectCollection.Loggers)
+            let items = projectInstance.GetItems("EmbeddedResource") |> Seq.map (fun i -> i.EvaluatedInclude, i.GetMetadata("ManifestResourceName").EvaluatedValue) |> Seq.toList
+            items
+        
+        /// Fallback for flags and sources. This is to handle the case in which the user has customized
+        /// the MSBuild so much that host compilation doesn't work/
+        let GetFlagsAndSourcesFallback(project:Project) : BuildFlags =
+            project.Build("ResolveReferences") |> ignore
+            let sources = items project "Compile"
+            let references = items project "ReferencePath"
+            let defineConstants=splitProperty project "DefineConstants"
+            let flags = (defineConstants |> List.map (sprintf "--define:%s")) @
+                            (references |> List.map(sprintf "-r:%s"))
+            {flags=flags
+             sources = sources}
+
+        /// Compute the Flags and Sources 
+        let GetFlagsAndSources(project:Project, host:HostCompile) : BuildFlags = 
+            let result =
+                use t = Trace.Call("MSBuildPerf","Calling compile to get flags", fun _-> "")
+                use xx = host.CaptureSourcesAndFlagsWithoutBuildingForABit()
+                project.IsBuildEnabled <- true
+                    
+                let loggers = 
+                    if Trace.ShouldLog("MSBuild") then
+                        seq { yield (new Microsoft.Build.BuildEngine.ConsoleLogger(LoggerVerbosity.Detailed) :> ILogger) }
+                    else 
+                        [] :> seq<ILogger>
+                            
+                let r = project.Build("Compile", loggers)
+                if not(r) then
+                    printfn "MSBuild result: %A" r
+                    printfn "%s" project.FullPath
+                    System.Diagnostics.Debug.Assert(false, "things are about to fail, as MSBuild failed; it would behoove you to turn on MSBuild tracing")
+                let capturedFlags, capturedSources = host.Results
+                {flags = capturedFlags |> Array.toList 
+                 sources = capturedSources |> Array.toList }
+            let Canonicalize (filename:string) = 
+                if System.IO.Path.IsPathRooted(filename) then
+                    Internal.Utilities.FileSystem.Path.SafeGetFullPath(filename)
+                else
+                    Internal.Utilities.FileSystem.Path.SafeGetFullPath(System.IO.Path.Combine(System.IO.Path.GetDirectoryName(project.FullPath),filename))
+            { flags = result.flags 
+              sources = result.sources |> List.map Canonicalize }
+            
+        let CrackProject(projectFileName, configuration, platform) =
+            use t = Trace.Call("MSBuild","crackProject", fun _-> sprintf " project=%s" projectFileName)
+            
+            let project,created,host = GetProject(projectFileName, configuration, platform)
+            Trace.PrintLine("MSBuild", fun _ -> sprintf "Project text:\n %s " (File.ReadAllText(projectFileName)))
+
+            try        
+                try 
+                    let result = GetFlagsAndSources(project,host)
+                    Trace.PrintLine("MSBuild", fun _ -> sprintf "Resolved flags and sources:\n %A \n %A" result.flags result.sources)
+                    result
+                with e -> 
+                    System.Diagnostics.Debug.Assert(false, sprintf "Bug seen in MSBuild CrackProject: %s %s %s\n" (e.GetType().Name) e.Message (e.StackTrace))
+                    reraise()
+            finally
+                if created then
+                    MSBuildProject.FullyUnloadProject(GlobalEngine(), project)
+   
+    let CreateFSharpManifestResourceName  projectFileName configuration platform =
+        MSBuild.CreateFSharpManifestResourceName(projectFileName,configuration,platform)
+
+    module Filenames = 
+        /// Compare two file names to eachother.
+        let AreSame f1 f2 = 
+            let result = 
+                   System.String.Compare(f1,f2,StringComparison.CurrentCultureIgnoreCase)=0
+                || System.String.Compare(Internal.Utilities.FileSystem.Path.SafeGetFullPath(f1),Internal.Utilities.FileSystem.Path.SafeGetFullPath(f2),StringComparison.CurrentCultureIgnoreCase)=0
+            result                                    
+
+    type MSBuildProjectSite(projectfile,configurationFunc,platformFunc) = 
+        let projectPath = Path.GetDirectoryName(projectfile)
+        let timestamp = ref (new DateTime())
+        let flags = ref None
+        let prevConfig = ref ""
+        let prevPlatform = ref ""
+        let GetFlags() = 
+            let newtimestamp = File.GetLastWriteTime(projectfile)
+            let curConfig = configurationFunc()
+            let curPlatform = platformFunc()
+            if (!timestamp)<>newtimestamp 
+                   || (!flags) = None 
+                   || (!prevConfig)<>curConfig
+                   || (!prevPlatform)<>curPlatform then
+                Trace.PrintLine("ProjectSite", fun _ -> sprintf "Timestamp of %s changed. New timestamp=%A, old timestamp=%A" projectfile newtimestamp !timestamp) 
+                timestamp := newtimestamp
+                prevConfig := curConfig
+                prevPlatform := curPlatform
+                flags := Some(MSBuild.CrackProject(projectfile, !prevConfig, !prevPlatform))
+            match (!flags) with
+                Some(flags) -> flags
+                | _ -> raise Error.Bug
+        let changeHandlers =  new System.Collections.Generic.Dictionary<string,Microsoft.VisualStudio.FSharp.LanguageService.AdviseProjectSiteChanges>()
+        member x.TriggerChanges() = 
+            for handler in changeHandlers do 
+                handler.Value.Invoke()
+
+        override this.ToString() = projectfile
+
+        interface IProjectSite with
+          member this.SourceFilesOnDisk() = 
+              let flags = GetFlags()
+              flags.sources 
+              |> List.map(fun s->Path.Combine(projectPath, s)) |> List.toArray 
+          member this.DescriptionOfProject() = 
+              let flags = GetFlags()
+              try sprintf "MSBuild Flags:%A\n%A" ((this :> IProjectSite).CompilerFlags()) flags
+              with e -> sprintf "%A" e                    
+          member this.CompilerFlags() = 
+              let flags = GetFlags()
+              let result = flags.flags
+              Trace.PrintLine("ProjectSite", fun _ -> sprintf "MSBuild flags were %A." result) 
+              result |> List.toArray 
+          member this.ProjectFileName() = 
+              projectfile
+          member this.ErrorListTaskProvider() = None
+          member this.ErrorListTaskReporter() = None
+          member this.AdviseProjectSiteChanges(callbackOwnerKey,callback) = changeHandlers.[callbackOwnerKey] <- callback
+          member this.AdviseProjectSiteCleaned(callbackOwnerKey,callback) = () // no unit testing support here
+          member this.IsTypeResolutionValid = true
+          member this.TargetFrameworkMoniker = ""
+          member this.LoadTime = new System.DateTime(2000,1,1)
+        
+    // Attempt to treat as MSBuild project.
+    let internal NewMSBuildProjectSite(configurationFunc, platformFunc, msBuildProjectName) = 
+        let newProjectSite = new MSBuildProjectSite(msBuildProjectName,configurationFunc,platformFunc)
+        newProjectSite
+        
+    /// Token types.
+    type TokenType = Text | Keyword | Comment | Identifier | String | Number | InactiveCode | PreprocessorKeyword | Operator
+        with override this.ToString() =
+            match this with
+            | Text                  -> "Text"
+            | Keyword               -> "Keyword"
+            | Comment               -> "Comment"
+            | Identifier            -> "Identifier"
+            | String                -> "String"
+            | Number                -> "Number"
+            | InactiveCode          -> "InactiveCode"
+            | PreprocessorKeyword   -> "PreprocessorKeyword"
+            | Operator              -> "Operator"
+
+    /// Declaration types.
+    type DeclarationType = 
+        | Class =0
+        | Constant = 6
+        | FunctionType = 12             // Like 'type FunctionType=unit->unit' 
+        | Enum = 18
+        | EnumMember = 24
+        | Event =30
+        | Exception = 36
+        | Interface = 48
+        | Method = 72
+        | FunctionValue = 74            // Like 'type Function x = 0'
+        | Module = 84
+        | Namespace = 90
+        | Property = 102
+        | ValueType = 108               // Like 'type ValueType=int*int' 
+        | RareType = 120                // Bucket for unusual types like 'type AsmType = (# "!0[]" #)'
+        | Record = 126
+        | DiscriminatedUnion = 132
+        
+    type BuildAction =
+        | Compile = 0
+        | EmbeddedResource = 1
+        | None = 2  
+
+    /// A file on disk.
+    type File = interface
+        end    
+    /// An error
+    [<Sealed>]
+    type Error(path: string, subcategory:string, msg: string, context: Microsoft.VisualStudio.TextManager.Interop.TextSpan, sev: Microsoft.VisualStudio.FSharp.LanguageService.Severity) = 
+        member e.Path = path
+        member e.Subcategory = subcategory
+        member e.Message = msg
+        member e.Context = context
+        member e.Severity = sev
+        override e.ToString() = 
+            sprintf "%s(%d,%d): %s %A : %s\n" path context.iStartLine context.iStartIndex subcategory sev msg
+    
+    type ChangeCallBack = IVsHierarchy * string -> unit
+    
+    /// Hooks for controlling behaviors
+    [<NoEquality; NoComparison>]
+    type ProjectBehaviorHooks = {
+        CreateProjectHook:(*projectFilename:*)string->(*files:*)(string*BuildAction*string option) list->(*references:*)(string*bool) list->(*projReferences:*)string list->
+                  (*disabledWarnings:*)string list->(*defines*)string list->(*versionFile:*)string->(*otherFlags:*)string->(*preImportXml:*)string->(*targetFrameworkVersion*)string->unit
+        InitializeProjectHook : OpenProject -> unit
+        MakeHierarchyHook : string->string->string->ChangeCallBack->OleServiceProvider->IVsHierarchy
+        AddFileToHierarchyHook : string -> IVsHierarchy -> unit
+        BuildHook : (*basename:*)string -> (*target:*)string -> IVsOutputWindowPane -> BuildResult
+        GetMainOutputAssemblyHook : string -> string
+        SaveHook : unit -> unit
+        DestroyHook : unit->unit
+        ModifyConfigurationAndPlatformHook : string->unit
+    }    
+    
+    /// A file open in VS.
+    and OpenFile = interface
+        // host VS
+        abstract VS : VisualStudio
+        end
+    /// A project open in VS.
+    and OpenProject = interface
+        // host VS
+        abstract VS : VisualStudio
+        end
+    /// Private part of OpenProject
+    and IOpenProject = 
+        /// Add a file to this project.
+        abstract AddFileFromText : string*string*BuildAction*string list->File
+        /// Add a file to this project as a linked file.
+        abstract AddLinkedFileFromText : string*string*string*BuildAction*string list->File
+        /// Open a file that is a member of this project.
+        abstract OpenFile : string->OpenFile
+        /// Errors (task list) associated with this project
+        abstract Errors : Error list with get
+        /// Add an assembly reference to the project
+        abstract AddAssemblyReference : string * bool -> unit        
+        /// Add a project reference to the project        
+        abstract AddProjectReference : OpenProject -> unit
+        /// Set the version file for this project
+        abstract SetVersionFile : string -> unit
+        /// Set other flags for this project
+        abstract SetOtherFlags : string -> unit
+        /// Set the defines for this project.
+        abstract SetProjectDefines : string list -> unit
+        /// Simulate typing into a project file right before the Import
+        abstract PlaceIntoProjectFileBeforeImport : string -> unit
+        /// Add a new disabled warning.
+        abstract AddDisabledWarning : string -> unit
+        /// Build the project. As CTRL+SHIFT+B in VS.  Can pass null for default target (build).
+        abstract Build : target:string -> BuildResult
+        /// Get the name to the main output assembly for the current configuration.
+        abstract GetMainOutputAssembly : unit -> string        
+        /// Save the project.
+        abstract Save : unit -> unit
+        /// Close the project.
+        abstract Close : unit -> unit
+        /// The project directory.
+        abstract Directory : string with get
+        /// The project file (e.g. foo.fsproj).
+        abstract ProjectFile : string with get
+        /// List of already opened files.
+        abstract GetOpenFiles : unit->OpenFile list
+        /// MSBuild '$(Configuration)|$(Platform)'
+        abstract ConfigurationAndPlatform : string with get
+        abstract ConfigurationAndPlatform : string with set
+
+    /// A solution open in VS.
+    and OpenSolution = interface
+        // host VS
+        abstract VS : VisualStudio
+        end
+    
+    // Private half of the OpenSolution interface
+    and IOpenSolution = 
+        
+        /// Create a new project of the given behaviorHooks that is open in VS.
+        abstract CreateProjectFlavor : ProjectBehaviorHooks->string->OpenProject
+        /// Close the solution.
+        abstract Close : unit -> unit
+
+
+    /// General purpose methods. Loosely represents running instance of VS.
+    and VisualStudio = interface
+        abstract VsOps : VsOps
+        end
+     
+    /// Private half of the Visual Studio interface   
+    and IVisualStudio =
+        abstract CreateSolution : unit -> OpenSolution
+        abstract OnIdle : unit->unit
+        abstract ShiftKeyUp : unit->unit
+        abstract ShiftKeyDown : unit->unit
+        // Wait long enough for background compile to complete.
+        abstract TakeCoffeeBreak : unit->unit
+        abstract CleanUp : unit->unit
+        abstract ClearLanguageServiceRootCachesAndCollectAndFinalizeAllTransients : unit -> unit
+        /// Open a previously-created project
+        abstract OpenExistingProject : ProjectBehaviorHooks->(*dir:*)string->(*projName:*)string->OpenProject*OpenSolution
+        abstract CleanInvisibleProject : unit -> unit
+        
+    and TextSpan       = Microsoft.VisualStudio.TextManager.Interop.TextSpan
+    and GotoDefnResult = Microsoft.VisualStudio.FSharp.LanguageService.GotoDefinitionResult
+    
+
+    // Result of querying the completion list
+    and CompletionItem = string * string * (unit -> string) * DeclarationType
+
+    /// Representes the information that is displayed in the navigation bar
+    and NavigationBarResult = 
+      { TypesAndModules : DropDownMember[]
+        Members : DropDownMember[]
+        SelectedType : int
+        SelectedMember : int }
+        
+    /// Methods for simulating VisualStudio    
+    and [<NoEquality; NoComparison>] VsOps = {
+        CreateVisualStudio                    : unit -> VisualStudio
+        CreateSolution                        : VisualStudio -> OpenSolution
+        GetOutputWindowPaneLines : VisualStudio -> string list
+        CloseSolution                         : OpenSolution ->unit
+        CreateProject                         : OpenSolution * string -> OpenProject
+        CreateProjectWithHooks                : OpenSolution * ProjectBehaviorHooks * string -> OpenProject
+        NewFile                               : VisualStudio * string * BuildAction * string list -> File
+        DeleteFileFromDisk : File -> unit
+        AddFileFromText                       : OpenProject * string * string * BuildAction * string list -> File
+        AddLinkedFileFromText                 : OpenProject*string*string*string*BuildAction*string list->File
+        AddAssemblyReference                  : OpenProject * string * bool -> unit 
+        AddProjectReference                   : OpenProject * OpenProject -> unit 
+        ProjectDirectory                      : OpenProject -> string
+        ProjectFile                           : OpenProject -> string
+        SetVersionFile                        : OpenProject * string -> unit
+        SetOtherFlags                         : OpenProject * string -> unit
+        SetConfigurationAndPlatform           : OpenProject * string -> unit
+        AddDisabledWarning                    : OpenProject * string -> unit
+        GetErrors                             : OpenProject -> Error list 
+        BuildProject                          : OpenProject * string -> BuildResult
+        GetMainOutputAssembly                 : OpenProject -> string
+        SaveProject                           : OpenProject -> unit        
+        OpenFileViaOpenFile                   : VisualStudio * string -> OpenFile
+        OpenFile                              : OpenProject * string -> OpenFile 
+        GetOpenFiles                          : OpenProject -> OpenFile list
+        SetProjectDefines                     : OpenProject * string list -> unit
+        PlaceIntoProjectFileBeforeImport      : OpenProject * string -> unit
+        OpenExistingProject                   : VisualStudio * string * string -> OpenProject * OpenSolution
+        MoveCursorTo                          : OpenFile * int * int -> unit
+        GetCursorLocation                     : OpenFile -> int * int
+        GetLineNumber                         : OpenFile -> int -> string
+        GetAllLines                           : OpenFile -> string list
+        SwitchToFile                          : VisualStudio * OpenFile -> unit
+        OnIdle                                : VisualStudio -> unit
+        ShiftKeyDown                          : VisualStudio -> unit
+        ShiftKeyUp                            : VisualStudio -> unit
+        TakeCoffeeBreak                       : VisualStudio -> unit 
+        ReplaceFileInMemory                   : OpenFile * string list * bool -> unit
+        SaveFileToDisk                        : OpenFile -> unit
+        CleanUp                               : VisualStudio -> unit 
+        CleanInvisibleProject                 : VisualStudio -> unit
+        ClearLanguageServiceRootCachesAndCollectAndFinalizeAllTransients : VisualStudio -> unit        
+        GetSquiggleAtCursor                   : OpenFile -> (Microsoft.VisualStudio.FSharp.LanguageService.Severity * string) option
+        GetSquigglesAtCursor                  : OpenFile -> (Microsoft.VisualStudio.FSharp.LanguageService.Severity * string) list
+        AutoCompleteAtCursor                  : OpenFile -> CompletionItem array
+        CompleteAtCursorForReason             : OpenFile * Microsoft.VisualStudio.FSharp.LanguageService.BackgroundRequestReason -> CompletionItem array
+        CompletionBestMatchAtCursorFor        : OpenFile * string * string option -> (string * bool * bool) option
+        MoveCursorToEndOfMarker               : OpenFile * string -> unit
+        MoveCursorToStartOfMarker             : OpenFile * string -> unit
+        GetQuickInfoAtCursor                  : OpenFile -> string   
+        GetQuickInfoAndSpanAtCursor           : OpenFile -> string * TextSpan   
+        GetMatchingBracesForPositionAtCursor  : OpenFile -> (TextSpan * TextSpan) array
+        GetNameOfOpenFile                     : OpenFile -> string
+        GetCheckOptionsOfScript               : OpenFile -> Microsoft.FSharp.Compiler.SourceCodeServices.CheckOptions
+        GetParameterInfoAtCursor              : OpenFile -> MethodListForAMethodTip
+        GetParameterInfoAtCursorNoFallback    : OpenFile -> MethodListForAMethodTip
+        GetTokenTypeAtCursor                  : OpenFile -> TokenType
+        GetIdentifierAtCursor                 : OpenFile -> (string * int) option
+        GetF1KeywordAtCursor                  : OpenFile -> string option
+        GotoDefinitionAtCursor                : OpenFile -> bool -> GotoDefnResult
+        GetNavigationContentAtCursor          : OpenFile -> NavigationBarResult
+        GetHiddenRegionCommands               : OpenFile -> list<NewHiddenRegion> * Map<uint32, TextSpan>
+        CreatePhysicalProjectFileInMemory     : ((*files:*)(string*BuildAction*string option) list) ->
+                                                ((*references:*)(string*bool) list) ->
+                                                ((*projectReferences:*)string list) ->
+                                                ((*disabledWarnings:*)string list) ->
+                                                ((*defines:*)string list) ->
+                                                (*versionFile*) string ->
+                                                ((*otherFlags:*)string) ->
+                                                ((*otherProjMisc:*)string) -> 
+                                                ((*targetFrameworkVersion*)string) -> string
+        /// True if files outside of the project cone are added as links.
+        AutoCompleteMemberDataTipsThrowsScope : string -> System.IDisposable
+        OutOfConeFilesAreAddedAsLinks         : bool
+        SupportsOutputWindowPane : bool
+    }      
+
+    [<AutoOpen>]
+    module GotoDefnResultExtensions = 
+        type Microsoft.VisualStudio.FSharp.LanguageService.GotoDefinitionResult with
+            member this.ToOption() = if this.Success then Some(this.Span, this.Url) else None
+
+
+    let maxErrors = 25
+    
+    /// Private implementation details.
+    module (*private*) Privates = 
+        let mutable private cookie = 0u;
+        let private nextRdtID() = 
+            cookie<-cookie+1u
+            cookie
+        let private nextItemId() = 
+            cookie<-cookie+1u
+            cookie
+        let private addFileToHier filename hier =
+            let itemid = nextItemId()
+            VsMocks.addRootChild hier itemid filename
+            
+        /// Patch keyboard
+        let private PatchKeyboard shiftKeyDown = 
+            let pressed flag = if flag then -1s else 0s
+            let getKeyState key =
+                match key with 
+                | Keyboard.Keys.Shift-> pressed shiftKeyDown 
+                | _ -> pressed false
+            Keyboard.HookGetKeyState getKeyState
+
+        type (*private*) UndoAction =
+              DeleteFile of string
+            | RemoveFolder of string
+            
+        type (*private*) Point = {line:int; col:int}
+            
+
+        /// Find the given marker and return the line and column.
+        let private IsolateMarkerSite (tl:IVsTextLines) (marker:string) : Point= 
+            let _, linecount = tl.GetLineCount()
+            let mutable returnLine = -1
+            let mutable returnCol = -1
+            let mutable i = 1
+            while i <= linecount do
+                let _, len = tl.GetLengthOfLine(i-1)
+                let _, text = tl.GetLineText(i-1,0,i-1,len)
+                let markerPos = text.IndexOf(marker)
+                if -1 <> markerPos then
+                    returnLine <- i
+                    returnCol <- markerPos + marker.Length + 1
+                    i <- linecount
+                    ()
+                i <- i + 1
+                
+            if returnLine = -1 then 
+                raise <| MarkerNotFoundException(marker)
+            else
+                {line = returnLine; col = returnCol}
+        
+        /// Colorize a single line of text.
+        let ColorizeLine (colorizer:FSharpColorizer) lineNumber lineText oldState attrs = 
+            let marshaled = Marshal.StringToCoTaskMemUni(lineText)
+            let newState = colorizer.ColorizeLine(lineNumber, lineText.Length, marshaled, oldState, attrs)
+            Marshal.FreeCoTaskMem(marshaled)
+            newState
+
+        /// Recolorize a set of lines
+        let RecolorizeLines (view:IVsTextView) (getColorizer:IVsTextView->FSharpColorizer) (lines:string[]) (linestarts:int[]) (top:int) (bottom:int) = 
+            let colorizer = getColorizer(view)
+            for i in top..bottom do 
+                // let attrs = Array.create fileline.Length 0u 
+                linestarts.[i+1] <- ColorizeLine colorizer i lines.[i] linestarts.[i] null            
+           
+        /// A constant value needed by the colorizer. 
+        let humanTextAttribute = ((uint32) (int32 COLORIZER_ATTRIBUTE.HUMAN_TEXT_ATTR))
+        
+        /// Remove the bits given bits from the original.
+        let Mask orig remove = orig &&& (0xffffffffu-remove)
+        
+        /// Create text of an MSBuild project with the given files and options.
+        let CreateMsBuildProjectText 
+                (useInstalledTargets : bool)
+                (files:(string*BuildAction*string option) list) 
+                (references:(string*bool) list) 
+                (projectReferences:string list) 
+                (disabledWarnings:string list) 
+                (defines:string list) 
+                versionFile 
+                (otherFlags:string) 
+                (otherProjMisc:string)
+                (targetFrameworkVersion:string) =        
+
+            // Determine which FSharp.targets file to use. If we use the installed
+            // targets file then we check the registry for F#'s install path. Otherwise
+            // we look in the same directory as the Unit Tests assembly.
+            let targetsFileFolder =
+                if useInstalledTargets 
+                then Option.get Internal.Utilities.FSharpEnvironment.BinFolderOfDefaultFSharpCompiler
+                else System.AppDomain.CurrentDomain.BaseDirectory
+            
+            let sb = new System.Text.StringBuilder()
+            let Append (text:string) = 
+                Trace.PrintLine("Salsa", fun _ -> text)
+                sb.Append(text+"\r\n") |> ignore
+            Append "<Project ToolsVersion='4.0' DefaultTargets='Build' xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>"
+            Append "    <PropertyGroup>"
+//            The salsa layer does Configuration/Platform in a kind of hacky way
+//            Append "        <Configuration Condition=\" '$(Configuration)' == '' \">Debug</Configuration>"
+//            Append "        <Platform Condition=\" '$(Platform)' == '' \">AnyCPU</Platform>"
+            Append "        <OutputPath>bin\Debug\</OutputPath>"  
+            if versionFile<>null then Append (sprintf "        <VersionFile>%s</VersionFile>" versionFile)
+            if otherFlags<>null then Append (sprintf "        <OtherFlags>%s --resolutions</OtherFlags>" otherFlags)
+            if targetFrameworkVersion<>null then
+                Append(sprintf "       <AllowCrossTargeting>true</AllowCrossTargeting>")
+                Append(sprintf "       <TargetFrameworkVersion>%s</TargetFrameworkVersion>" targetFrameworkVersion)
+            Append "        <NoWarn>"
+            for disabledWarning in disabledWarnings do
+                Append (sprintf "            %s;" disabledWarning)                            
+            Append "        </NoWarn>"
+            Append "        <DefineConstants>"
+            for define in defines do
+                Append (sprintf "            %s;" define)                            
+            Append "        </DefineConstants>"            
+            
+            Append "    </PropertyGroup>"
+//            Append "    <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' \">"
+//            Append "        <OutputPath>bin\Debug\</OutputPath>"
+//            Append "    </PropertyGroup>"
+//            Append "    <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' \">"
+//            Append "        <OutputPath>bin\Release\</OutputPath>"
+//            Append "    </PropertyGroup>"
+
+            Append "    <ItemGroup>"
+            
+            for (reference,specificVersion) in references do
+                Append (sprintf "        <Reference Include=\"%s\">" reference)                
+                if specificVersion then
+                    Append (sprintf "            <SpecificVersion>true</SpecificVersion>")                
+                Append (sprintf "        </Reference>")                
+
+            for projectReference in projectReferences do
+                Append (sprintf "        <ProjectReference Include=\"%s\">" projectReference)                
+                Append "            <Name>SomeReferencedProject</Name>"     
+                Append "            <Project>{45636601-CA91-4382-B8BB-3DBD03BF3F56}</Project>"                
+                Append "        </ProjectReference>"
+
+            for (file,buildAction,link) in files do
+                let operation = 
+                    match buildAction with
+                    | BuildAction.None -> "None"
+                    | BuildAction.EmbeddedResource -> "EmbeddedResource"
+                    | BuildAction.Compile -> "Compile"
+                    | _ -> failwith "unexpected"
+                    
+
+                    
+                match link with 
+                | None ->
+                    Append (sprintf "        <%s Include='%s'/>" operation file)
+                | Some link ->
+                    Append (sprintf "        <%s Include='%s'>" operation file)
+                    Append (sprintf "            <Link>%s</Link>" link)
+                    Append (sprintf "        </%s>" operation)
+                
+            Append "    </ItemGroup>"
+            Append otherProjMisc
+            
+            Append (sprintf "    <Import Project=\"%s\\Microsoft.FSharp.targets\"/>" targetsFileFolder)
+            Append "</Project>"
+            Trace.PrintLine("Salsa", fun _ -> sprintf "Project text:\n%s" (sb.ToString()) )
+            
+            sb.ToString()
+
+        /// Create an MSBuild project at the given location with the given files and options.
+        let CreateMsBuildProject 
+                (useInstalledTargets : bool)
+                projectName 
+                (files:(string*BuildAction*string option) list) 
+                (references:(string*bool) list) 
+                (projectReferences:string list) 
+                (disabledWarnings:string list) 
+                (defines:string list) 
+                versionFile 
+                (otherFlags:string)
+                (preImportXml : string)
+                (targetFrameworkVersion : string) =
+            use t = Trace.Call("Salsa", "CreateMsBuildProject", fun _ -> sprintf " projectName=%s" projectName)
+            if File.Exists(projectName) then File.Delete(projectName)
+
+            let text = CreateMsBuildProjectText useInstalledTargets files references projectReferences disabledWarnings defines versionFile otherFlags preImportXml targetFrameworkVersion
+            Trace.PrintLine("Salsa", fun _ -> text)
+            File.AppendAllText(projectName,text+"\r\n")
+            
+            
+
+        let MakeMSBuildBehavior() = 
+            let openProject : IOpenProject option ref= ref None
+            let ConfPlat() = 
+                let s = (!openProject).Value.ConfigurationAndPlatform
+                dprintf "%s" s
+                let i = s.IndexOf('|')
+                if i = -1 then
+                    s,""
+                else
+                    s.Substring(0,i), s.Substring(i+1)
+            let Conf() = let c,_ = ConfPlat() in c
+            let Plat() = let _,p = ConfPlat() in p
+            {
+            CreateProjectHook       = CreateMsBuildProject false    // Don't use installed FSharp.targets file
+            InitializeProjectHook   = fun op -> openProject := Some(op:?>IOpenProject)
+            MakeHierarchyHook       = (fun projdir fullname projectname configChangeNotifier serviceProvider->
+                let projectSite = NewMSBuildProjectSite(Conf, Plat, fullname)
+                let projectSiteFactory = { new IProvideProjectSite with member x.GetProjectSite() = (projectSite :> IProjectSite) }
+                let hier = VsMocks.createHier(projectSiteFactory)
+                VsMocks.setHierRoot hier projdir projectname
+                hier)
+            AddFileToHierarchyHook  = addFileToHier
+            BuildHook               = fun baseName target outputWindowPane -> MSBuild.Build(baseName, (if target = null then "Build" else target), Conf(), Plat())
+            GetMainOutputAssemblyHook = fun baseName -> MSBuild.GetMainOutputAssembly(baseName, Conf(), Plat())
+            SaveHook                = fun () -> ()
+            DestroyHook             = fun()->()
+            ModifyConfigurationAndPlatformHook = fun _ -> ()
+            }     
+
+        type SimpleVisualStudio(configChangeNotifier,serviceProvider, ops : VsOps) =                 
+            let mutable shiftKeyDown = false
+            let mutable languageService : LanguageServiceState option = None
+            let mutable undoStack:UndoAction list = []
+            let mutable focusFile : SimpleOpenFile option = None
+            let mutable solution : SimpleOpenSolution option = None
+            let mutable prevSolutions : Map<string,SimpleOpenSolution> = Map.empty
+            let mutable bufferToSource = new Dictionary<IVsTextBuffer,IdealSource>()
+            let mutable invisibleSolution : SimpleOpenSolution option = None
+            let mutable invisibleProjectFolder : string = null
+            let mutable invisibleProject : SimpleOpenProject option = None
+            let mutable configChangeNotifier : IVsHierarchy * string -> unit = configChangeNotifier
+            let mutable serviceProvider : OleServiceProvider = serviceProvider
+            let currentOutputWindowLines = ref []
+            let outputWindowPane = VsMocks.vsOutputWindowPane(currentOutputWindowLines)
+            
+            let fileChangeEx = VsMocks.VsFileChangeEx()
+            
+            let ReopenSolution fullname =
+                match prevSolutions.TryFind fullname with
+                | Some(s) -> prevSolutions <- prevSolutions.Remove fullname
+                             s
+                | None -> failwith "solution with that project does not exist"
+                
+            member vs.FileChangeEx = fileChangeEx     
+            
+            member vs.ConfigChangeNotifier = configChangeNotifier           
+            member vs.ServiceProvider = serviceProvider    
+            member vs.OutputWindowPane = outputWindowPane       
+                
+            member private vs.InvisibleSolution() = 
+                match invisibleSolution with
+                | None ->
+                    let s = SimpleOpenSolution(vs)
+                    invisibleSolution <- Some(s)
+                    s
+                | Some(s) -> s
+                
+            member private vs.InvisibleProject(behaviorHooks:ProjectBehaviorHooks) = 
+                match invisibleProject with
+                | None ->
+                    let projdir = NewTempDirectory "salsa-invis"
+                    invisibleProjectFolder <- projdir
+                    vs.PushUndo(RemoveFolder(projdir))
+                    
+                    let p = SimpleOpenProject(vs.InvisibleSolution(),null,projdir,"invisible.fsproj",behaviorHooks)
+                    invisibleProject <- Some(p)
+                    p
+                | Some(p) -> p
+                
+            member vs.NewFile(filename:string,buildAction:BuildAction,lines:string list,behaviorHooks:ProjectBehaviorHooks) =
+                let p : IOpenProject = upcast vs.InvisibleProject(behaviorHooks)
+                p.AddFileFromText(filename,filename,buildAction,lines)
+                
+            member vs.OpenFileViaOpenFile(filename:string,behaviorHooks:ProjectBehaviorHooks) =
+                let p : IOpenProject = upcast vs.InvisibleProject(behaviorHooks)
+                p.OpenFile(filename)
+                
+            member vs.LanguageService 
+                with get() = 
+                    match languageService with
+                    | Some(languageService) -> languageService
+                    | None -> failwith "No salsa language service available."  
+                and set(value) =
+                    languageService <- Some(value)
+                 
+            member vs.IsShiftKeyDown = shiftKeyDown
+            member vs.PushUndo(u) = 
+                Trace.PrintLine("SalsaUndo", fun _ -> sprintf "Pushing cleanup action %A" u)
+                undoStack<-u::undoStack
+            member vs.GetColorizer(view:IVsTextView) =
+                    let _,buffer = view.GetBuffer()
+                    vs.LanguageService.GetColorizer(buffer)
+            member vs.FocusOpenFile(fileToFocus:SimpleOpenFile) =
+                focusFile<-Some(fileToFocus)
+            member vs.CloseSolution(fullname) =
+                match solution with
+                | Some(s) ->
+                    prevSolutions <- prevSolutions.Add(fullname, s)
+                    solution <- None
+                | None -> failwith "there is no open solution"
+            
+            member vs.AddSourceForBuffer(buffer:IVsTextBuffer,source:IdealSource) =
+                bufferToSource.Add(buffer,source)
+
+            member vs.SourceFactory(buffer:IVsTextBuffer) =
+                bufferToSource.[buffer]
+                
+            member vs.GetOutputWindowPaneLines() = 
+                List.rev !currentOutputWindowLines
+                
+            // ---------------------------------------------------------
+            
+            interface VisualStudio with
+                member vs.VsOps = ops
+            
+            // ---------------------------------------------------------
+            
+            interface IVisualStudio with 
+                member vs.CleanInvisibleProject() = 
+                    if invisibleProjectFolder <> null then
+                        try Directory.Delete(invisibleProjectFolder, true) with _ -> ()
+                        invisibleProject <- None
+                member vs.CreateSolution() = 
+                    match solution with
+                    | Some solution -> (solution :> IOpenSolution).Close()
+                    | None -> ()
+                    let s = SimpleOpenSolution(vs) 
+                    solution <- Some(s)
+                    s :> OpenSolution
+                member solution.OpenExistingProject behaviorHooks projdir projectname =
+                    let fullname = Path.Combine(projdir,projectname+".fsproj")
+                    let soln = ReopenSolution fullname
+                    let proj = soln.OpenExistingProject behaviorHooks projdir projectname
+                    ((proj:>OpenProject),(soln:>OpenSolution))
+                member vs.OnIdle() = 
+                    vs.LanguageService.OnIdle()
+                    match focusFile with
+                    | Some(focusFile) -> focusFile.OnIdle()
+                    | None -> Trace.PrintLine("ChangeEvents", fun _ -> "In TakeCoffeeBreak there was no focus file to idle.")                 
+                member vs.ShiftKeyDown() = shiftKeyDown <- true
+                member vs.ShiftKeyUp() = shiftKeyDown <- false
+                member vs.TakeCoffeeBreak() = 
+                    vs.LanguageService.WaitForBackgroundCompile()
+                    (vs :> IVisualStudio).OnIdle()
+                    vs.LanguageService.WaitForBackgroundCompile()
+                    (vs :> IVisualStudio).OnIdle()
+                    vs.LanguageService.WaitForBackgroundCompile()
+                    (vs :> IVisualStudio).OnIdle()
+                    
+                member vs.ClearLanguageServiceRootCachesAndCollectAndFinalizeAllTransients() =
+                    vs.LanguageService.ClearLanguageServiceRootCachesAndCollectAndFinalizeAllTransients()
+                member vs.CleanUp() = 
+                    vs.LanguageService.Unhook()
+                    match solution with
+                    | Some(s) -> s.CleanUp()
+                    | _ -> ()
+                    prevSolutions |> Map.toList |> List.iter (fun (_,s) -> s.CleanUp())
+                    if true then
+                        let undoActions = undoStack
+                        undoStack<-[]
+                        undoActions |>
+                            List.iter(function
+                                      DeleteFile f -> 
+                                        Trace.PrintLine("SalsaUndo", fun _ -> sprintf "Performing undo action: DeleteFile %s" f)
+                                        try
+                                            File.Delete(f)
+                                        with e->
+                                            printf "Failed to Delete file '%s'" f
+                                            raise e
+                                    | RemoveFolder f -> 
+                                        Trace.PrintLine("SalsaUndo", fun _ -> sprintf "Performing undo action: RemoveFolder %s" f)
+                                        try 
+                                            if Directory.Exists(f) then Directory.Delete(f,true)
+                                        with 
+                                            | :? System.IO.IOException -> printf "Failed to Remove folder '%s'" f
+                                            | e->
+                                                printf "Failed to Remove folder '%s'" f
+                                                raise e)
+        and internal SimpleOpenSolution(vs:SimpleVisualStudio) as this = 
+            let mutable curProjects : (string*SimpleOpenProject) list = []
+            let mutable prevProjects : Map<string,SimpleOpenProject> = Map.empty
+            let MakeProject behaviorHooks projdir fullname projectname =
+                // Create the hierarchy to go with this project.
+                let hier = behaviorHooks.MakeHierarchyHook projdir fullname projectname vs.ConfigChangeNotifier vs.ServiceProvider
+
+                // The rest.
+                let p = new SimpleOpenProject(this,hier,projdir,fullname,behaviorHooks)
+                curProjects <- (fullname,p) :: curProjects
+                p :> OpenProject
+            let ReopenProject fullname =
+                match prevProjects.TryFind fullname with
+                | Some(p) -> prevProjects <- prevProjects.Remove fullname
+                             p
+                | None -> failwith "project does not exist"
+            member solution.Vs = vs
+            member solution.CleanUp() = 
+                curProjects |> List.iter (fun (_,p) -> p.CleanUp())
+                prevProjects |> Map.toList |> List.iter (fun (_,p) -> p.CleanUp())
+            member solution.OpenExistingProject behaviorHooks projdir projectname =
+                let fullname = Path.Combine(projdir,projectname+".fsproj")
+                ReopenProject fullname :> OpenProject
+            
+            interface OpenSolution with
+                member solution.VS = vs :> _
+            
+            interface IOpenSolution with 
+                member solution.Close() =
+                    curProjects |> List.iter (fun (fullname,p) ->
+                        (p :> IOpenProject).Close()
+                        vs.CloseSolution fullname
+                        prevProjects <- prevProjects.Add(fullname, p)
+                    )
+                    curProjects <- []
+                member solution.CreateProjectFlavor behaviorHooks projectname =
+                    // Create the physical project directory.
+                    let projdir = NewTempDirectory "salsa"
+                    vs.PushUndo(RemoveFolder(projdir))
+                    
+                    // Put project in there.
+                    let fullname = Path.Combine(projdir, projectname+".fsproj")
+                    behaviorHooks.CreateProjectHook fullname [] [] [] [] [] null null "" null
+                    vs.PushUndo(DeleteFile(fullname))
+                    
+                    // Schedule obj\Debug and bin\Debug to be removed.
+                    vs.PushUndo(RemoveFolder(Path.Combine(projdir, "obj")))
+                    vs.PushUndo(RemoveFolder(Path.Combine(projdir, "bin")))
+                    
+                    MakeProject behaviorHooks projdir fullname projectname
+                    
+        and internal SimpleOpenProject(solution:SimpleOpenSolution,hier:IVsHierarchy,directory:string,projectName:string,behaviorHooks:ProjectBehaviorHooks) as this = 
+            let mutable configuration = ""
+            let mutable preImportXml = ""
+            let mutable errors:Error list = []
+            let mutable files:SimpleOpenFile list = []
+            let mutable filenames:(string*BuildAction*string option) list = []
+            let mutable references:(string*bool) list = []
+            let mutable projectReferences:string list = []
+            let mutable disabledWarnings:string list = []
+            let mutable defines:string list = []
+            let mutable versionFile : string = null
+            let mutable otherFlags : string = null
+            let CreateProjectFile() = 
+                behaviorHooks.CreateProjectHook 
+                                        projectName 
+                                        (List.rev filenames) 
+                                        (List.rev references) 
+                                        (List.rev projectReferences) 
+                                        (List.rev disabledWarnings) 
+                                        (List.rev defines)
+                                        versionFile
+                                        otherFlags
+                                        preImportXml
+                                        null
+                // Trigger the AdviseProjectSiteChanges callbacks on our project sites
+                match hier with 
+                | :? IProvideProjectSite as f -> 
+                    match f.GetProjectSite() with 
+                    | :? MSBuildProjectSite as m -> 
+                        m.TriggerChanges()
+                    | _ -> 
+                        ()
+                | _ -> 
+                    ()
+                                        
+            do
+                behaviorHooks.InitializeProjectHook(this :> OpenProject)
+            member project.Solution =solution
+            member project.Errors 
+                with get() = errors
+                and set(e) = errors <- e
+            member project.CleanUp() =
+                behaviorHooks.DestroyHook()
+
+            interface OpenProject with
+                member project.VS = solution.Vs :> _
+
+            interface IOpenProject with
+                member project.Close() =
+                    List.iter (fun (f : SimpleOpenFile) -> f.Close()) files
+                    behaviorHooks.DestroyHook()
+                member project.Directory 
+                    with get() = directory
+                member project.ProjectFile = Path.Combine(directory,projectName)
+                member project.AddFileFromText(filenameOnDisk, filenameInProject, buildAction, lines) = 
+                    // Record the filename without path.
+                    filenames <- (filenameInProject,buildAction,None)::filenames
+                    // Create the physical file.
+                    let filename = Path.Combine(directory, filenameOnDisk)
+                    File.WriteAllLines(filename, Array.ofList lines)
+                    CreateProjectFile()
+                    solution.Vs.PushUndo(DeleteFile(filename))
+                    SimpleFile(filename) :> File
+                member project.AddLinkedFileFromText(filenameOnDisk, includeFilenameInProject, linkFilenameInProject, buildAction, lines) = 
+                    // Record the filename without path.
+                    filenames <- (includeFilenameInProject,buildAction, Some linkFilenameInProject)::filenames
+                    // Create the physical file.
+                    let filename = Path.Combine(directory, filenameOnDisk)
+                    File.WriteAllLines(filename, Array.ofList lines)
+                    CreateProjectFile()
+                    solution.Vs.PushUndo(DeleteFile(filename))
+                    SimpleFile(filename) :> File
+                member project.Build(target) = 
+                    let outputWindowPane = solution.Vs.OutputWindowPane
+                    outputWindowPane.Clear() |> ignore
+                    let buildResult = behaviorHooks.BuildHook projectName target outputWindowPane
+                    let executableOutput = Path.Combine(directory,buildResult.ExecutableOutput)
+                    if target = "Clean" then
+                        project.Solution.Vs.FileChangeEx.DeletedFile(executableOutput) // Notify clients of IVsFileChangeEx
+                    else
+                        project.Solution.Vs.FileChangeEx.AddedFile(executableOutput) // Notify clients of IVsFileChangeEx
+                    {buildResult with ExecutableOutput=executableOutput}
+                member project.GetMainOutputAssembly() =
+                    Path.Combine(directory,behaviorHooks.GetMainOutputAssemblyHook(projectName))                
+                member project.Save() = 
+                    behaviorHooks.SaveHook()
+                member project.AddAssemblyReference(reference,specificVersion) = 
+                    references <- (reference,specificVersion)::references
+                    CreateProjectFile()
+                member project.AddDisabledWarning(code) = 
+                    disabledWarnings <- code::disabledWarnings
+                    CreateProjectFile()
+                member project.SetProjectDefines(definedConstants) = 
+                    defines <- definedConstants
+                    CreateProjectFile()
+                member project.PlaceIntoProjectFileBeforeImport(xml) = 
+                    preImportXml <- preImportXml + xml
+                    CreateProjectFile()
+                
+                member project.AddProjectReference(referencedProject) = 
+                    projectReferences <- (referencedProject:?>IOpenProject).ProjectFile :: projectReferences
+                    CreateProjectFile()
+                member project.SetVersionFile(file) = 
+                    versionFile <- file
+                    CreateProjectFile()
+                member project.SetOtherFlags(flags) = 
+                    otherFlags <- flags
+                    CreateProjectFile()                    
+                member project.OpenFile(filename) = 
+                    let filename = Path.Combine(directory, filename)
+                    
+                    // Opening a file that is already open does not create a new file it just opens that same file.
+                    match files |> List.tryFind(fun (opf:SimpleOpenFile)->opf.Filename = filename) with
+                    | Some(opf) -> 
+                        let file = opf :> OpenFile
+                        opf.EnsureInitiallyFocusedInVs()
+                        file
+                    | None ->   
+                        // Create the file with IVsTextView
+                        let lines = File.ReadAllLines(filename)
+                        let view = VsMocks.createTextView()
+                        let linestarts = Array.create (lines.Length+1) 0 // One extra to save the state at the end of the file.
+                        VsMocks.setFileText filename view lines (RecolorizeLines view solution.Vs.GetColorizer lines linestarts) (fun line->linestarts.[line])
+                        
+                        // The invisible project does not have a hiearchy.
+                        if hier <> null then 
+                            // Put the file in the hierarchy
+                            behaviorHooks.AddFileToHierarchyHook filename hier
+                        
+                        // Put the file in the text manager
+                        VsMocks.setActiveView (solution.Vs.LanguageService.ServiceProvider.TextManager) view                    
+                        
+                        // We no longer need the RDT, but keeping it compiling in Salsa/VsMocks in case we ever need it again
+                        // Put the document in the RDT
+                        let rdtId = nextRdtID()
+                        VsMocks.openDocumentInRdt (solution.Vs.LanguageService.ServiceProvider.Rdt) rdtId filename view hier
+                        // product no longer uses RDT
+                        // solution.Vs.LanguageService.OnAfterFirstDocumentLock rdtId 1u 1u
+
+                        // Create the 'Source'
+                        let file = SimpleOpenFile(project,filename,lines,view,linestarts,rdtId) 
+                        let source = Source.CreateDelegatingSource(file.RecolorizeWholeFile,
+                                                                   file.RecolorizeLine,
+                                                                   filename,
+                                                                   file.IsClosed,
+                                                                   project.Solution.Vs.FileChangeEx)
+                        let _,buf = view.GetBuffer()
+                        solution.Vs.AddSourceForBuffer(buf,source)                 
+                        let source = solution.Vs.LanguageService.CreateSource(buf)
+                        
+                        // Scan all lines with the colorizer
+                        let tcs:IVsTextColorState = downcast box(buf)
+                        let _ = tcs.ReColorizeLines(0,lines.Length-1)
+                        
+                        // dprintf "ScanStates=%A\n" linestarts
+                        // Return the file.
+                        files <- file :: files
+                        file.EnsureInitiallyFocusedInVs()
+                        // Idle a bit to here (allows the Language Service to do any background processing)
+                        (solution.Vs :> IVisualStudio).TakeCoffeeBreak()
+                        file :> OpenFile
+                member project.Errors 
+                    with get() = errors
+                member project.GetOpenFiles() =
+                    files |> List.map (fun f -> f :> OpenFile)
+                member project.ConfigurationAndPlatform with get() = configuration
+                                                        and set(s) = 
+                                                            configuration <- s
+                                                            behaviorHooks.ModifyConfigurationAndPlatformHook(s)
+        and internal SimpleFile(filename:string) =
+            interface File
+            member file.DeleteFileFromDisk() =
+                File.Delete(filename)
+        and internal SimpleOpenFile(project:SimpleOpenProject,filename:string,lines:string array,view:IVsTextView,scanlines:int[],rdtId) = 
+            let mutable lines  = lines
+            let mutable scanlines = scanlines
+            let mutable cursor:Point = {line=1;col=1}
+            let mutable isClosed = false
+            let mutable combinedLines:string = null
+            
+            member file.GetFileName() = filename
+            member file.GetCheckOptionsOfScript() = 
+                project.Solution.Vs.LanguageService.InteractiveChecker.GetCheckOptionsFromScriptRoot(filename, file.CombinedLines, System.DateTime(2000,1,1))
+                 
+            member file.RecolorizeWholeFile() = ()
+            member file.RecolorizeLine (_line:int) = ()
+            member file.IsClosed() = isClosed
+            member file.Filename = 
+                VsTextLines.GetFilename(Com.ThrowOnFailure1(view.GetBuffer()))
+            member file.OnIdle() =
+                while file.Source.NeedsVisualRefresh do
+                    file.OnIdleTypeCheck()
+            member file.CombinedLines =
+                if combinedLines = null then 
+                    combinedLines<-String.Join("\n",lines)
+                combinedLines   
+            member file.Source : IdealSource = 
+                let _,buf = view.GetBuffer()
+                project.Solution.Vs.SourceFactory(buf)                                       
+            
+            /// When a file is opened, focus it as the topmost file in VS.
+            member file.EnsureInitiallyFocusedInVs() =
+                project.Solution.Vs.FocusOpenFile(file)                    
+                                     
+            member file.TryExecuteBackgroundRequest(pr) = 
+                let ls = project.Solution.Vs.LanguageService
+                ls.ExecuteBackgroundRequest(pr, file.Source) 
+                if pr.ResultClearsDirtinessOfFile then 
+                    file.Source.RecordViewRefreshed()
+                pr.ResultScope 
+
+            member file.ExecuteBackgroundRequestForScope(pr,canRetryAfterWaiting) = 
+                match file.TryExecuteBackgroundRequest(pr) with 
+                | null when canRetryAfterWaiting -> 
+                    // OK, no scope is available. Try once more after waiting. The background compile should notify us that the
+                    // file becomes dirty again
+                    (project.Solution.Vs :> IVisualStudio).TakeCoffeeBreak()
+                    file.TryExecuteBackgroundRequest(pr) 
+                | res -> 
+                    res
+                    
+            /// This is the periodic check that VS                                     
+            member file.OnIdleTypeCheck() = 
+                // Remove errors for this file only
+                project.Errors <- project.Errors |> List.filter(fun err->err.Path <> file.Filename)
+                let ls = project.Solution.Vs.LanguageService
+                
+                // Full check.                    
+                let sink = new AuthoringSink(BackgroundRequestReason.FullTypeCheck, 0, 0, maxErrors) 
+                let snapshot = VsActual.createTextBuffer(file.CombinedLines).CurrentSnapshot 
+                let pr = project.Solution.Vs.LanguageService.CreateBackgroundRequest(0,0,new TokenInfo(),file.CombinedLines, snapshot, MethodTipMiscellany.Typing, Internal.Utilities.FileSystem.Path.SafeGetFullPath(file.Filename), BackgroundRequestReason.FullTypeCheck, view,sink,null,file.Source.ChangeCount,false)
+                pr.ResultSink.add_OnErrorAdded(
+                    OnErrorAddedHandler(fun path subcategory msg context severity -> 
+                                project.Errors <- new Error(path, subcategory, msg, context, severity) :: project.Errors))
+                file.ExecuteBackgroundRequestForScope(pr,canRetryAfterWaiting=false) |> ignore
+                    
+            member file.DoIntellisenseRequest(parseReason) =
+                if parseReason = BackgroundRequestReason.MemberSelect then
+                    // In the actual product, the only thing that can trigger MemberSelect is the auto-popup caused by the "." or ".." tokens (see service.fs:TokenClassifications.tokenInfo)
+                    // Thus, let's try to ensure that unit tests are only testing code paths from the actual product, and assert/fail if not.  Best effort.
+                    let lineIndex, colIndex = cursor.line-1, cursor.col-1
+                    System.Diagnostics.Debug.Assert(colIndex > 0, "hm, how did we invoke at start of line?")
+                    let colIndex = colIndex - 1 // cursor is just right of the char we want to inspect
+                    if lines.[lineIndex].[colIndex] <> '.' then
+                        // there could legally be whitespace or comments to the left, with a '.' left of that, and we have unit tests that do this, so accomodate that case as well, 
+                        // at least in the approximate way unit tests do it
+                        if lines.[lineIndex].Substring(0,colIndex+1).EndsWith("*)") && lines.[lineIndex].Contains(".(*") then
+                            // ok, this is probably fine, have cases like "System.(*marker*)"
+                            ()
+                        else
+                            //System.Diagnostics.Debug.Assert(false, "unit test is doing an AutoComplete MemberSelect at a non-dot location")
+                            failwith "unit test is probably doing an AutoComplete MemberSelect at a non-dot location, maybe should be CtrlSpaceComplete instead?"
+                file.EnsureInitiallyFocusedInVs()
+                let origKeyStateAccessor = PatchKeyboard project.Solution.Vs.IsShiftKeyDown
+                let currentAuthoringScope =
+                    let ti = new TokenInfo()
+                    let sink = new AuthoringSink(parseReason, cursor.line-1, cursor.col-1, maxErrors)
+                    let snapshot = VsActual.createTextBuffer(file.CombinedLines).CurrentSnapshot 
+                    let pr = project.Solution.Vs.LanguageService.CreateBackgroundRequest(
+                                                    cursor.line-1, cursor.col-1, ti, file.CombinedLines, snapshot, MethodTipMiscellany.Typing,
+                                                    Internal.Utilities.FileSystem.Path.SafeGetFullPath(file.Filename),
+                                                    parseReason, view, sink, null, file.Source.ChangeCount, false)
+                                                   
+                    file.ExecuteBackgroundRequestForScope(pr,canRetryAfterWaiting=true)
+
+                match currentAuthoringScope with
+                | null -> 
+                    System.Diagnostics.Debug.Assert(false, "No Authoring Scope was returned by ExecuteBackgroundRequest, even after waiting")
+                    failwith "No Authoring Scope" 
+                | _ -> 
+                    currentAuthoringScope, origKeyStateAccessor              
+
+
+            member file.GetCursorLocation() =
+                (cursor.line, cursor.col)
+            member file.MoveCursorTo(line,col) = 
+                file.EnsureInitiallyFocusedInVs()
+                if line=0 then failwith "Cursor points are 1-relative. Wrong line value."
+                if col=0 then failwith "Cursor points are 1-relative. Wrong col value."
+                cursor<-{line=line;col=col}
+            member file.MoveCursorToEndOfMarker(marker) = 
+                file.EnsureInitiallyFocusedInVs()
+                let _,tl = view.GetBuffer()
+                cursor <- IsolateMarkerSite tl marker
+            member file.MoveCursorToStartOfMarker(marker) = 
+                file.EnsureInitiallyFocusedInVs()
+                let _,tl = view.GetBuffer()
+                let c = IsolateMarkerSite tl marker
+                cursor <- {line=c.line;col=c.col-marker.Length}
+                // dprintf "Moved cursor to %A\n" cursor
+            
+            member file.GetQuickInfoAtCursor () = 
+                let (result, _) = file.GetQuickInfoAndSpanAtCursor()
+                result
+
+            member file.GetQuickInfoAndSpanAtCursor () = 
+                let (currentAuthoringScope, origKeyStateAccessor) = file.DoIntellisenseRequest BackgroundRequestReason.QuickInfo
+                try 
+                    let textspan = new TextSpan ()
+                    let result,textspan = currentAuthoringScope.GetDataTipText (cursor.line - 1, cursor.col - 1)
+                    let currentLineLength = lines.[cursor.line-1].Length
+                    // The new editor is less tolerant of values out of range. Enforce rigor in unittests here.
+                    if textspan.iEndIndex<0 || textspan.iEndIndex>currentLineLength then failwith (sprintf "GetDataTipText returned iEndIndex out of range. iEndIndex=%d, Line length=%d" textspan.iEndIndex currentLineLength)
+                    if textspan.iStartIndex<0 || textspan.iStartIndex>currentLineLength then failwith (sprintf "GetDataTipText returned iStartIndex out of range. iStartIndex=%d, Line length=%d" textspan.iStartIndex currentLineLength)
+                    if textspan.iStartIndex > textspan.iEndIndex then failwith (sprintf "GetDataTipText returned iStartIndex (%d) greater than iEndIndex (%d)" textspan.iStartIndex textspan.iEndIndex)
+                    result, textspan
+                finally 
+                    Keyboard.HookGetKeyState origKeyStateAccessor |> ignore
+
+            member file.GetMatchingBracesForPositionAtCursor() = 
+                file.EnsureInitiallyFocusedInVs()
+                let sink =
+                    let ti = new TokenInfo()
+                    let sink = new AuthoringSink(BackgroundRequestReason.MatchBraces, cursor.line-1, cursor.col-1, maxErrors)
+                    let snapshot = VsActual.createTextBuffer(file.CombinedLines).CurrentSnapshot 
+                    let pr = project.Solution.Vs.LanguageService.CreateBackgroundRequest(
+                                                    cursor.line-1, cursor.col-1, ti, file.CombinedLines, snapshot, MethodTipMiscellany.Typing,
+                                                    Internal.Utilities.FileSystem.Path.SafeGetFullPath(file.Filename),
+                                                    BackgroundRequestReason.MatchBraces, view, sink, null, file.Source.ChangeCount, false)
+                                                   
+                    file.ExecuteBackgroundRequestForScope(pr,canRetryAfterWaiting=false)
+                    |> ignore
+                    sink
+                [|
+                    for o in sink.Braces do
+                        match o with
+                        | (:? Microsoft.VisualStudio.FSharp.LanguageService.BraceMatch as m) -> 
+                            yield (m.a, m.b)
+                        | x -> failwith "Microsoft.VisualStudio.FSharp.LanguageService.BraceMatch expected, but got %A" (if box x = null then "null" else (x.GetType()).FullName)
+                |]
+
+                
+
+
+            member file.GetParameterInfoAtCursor(useNameResolutionFallback) = 
+                let currentAuthoringScope, origKeyStateAccessor = 
+                    file.EnsureInitiallyFocusedInVs()
+                    let origKeyStateAccessor = PatchKeyboard project.Solution.Vs.IsShiftKeyDown
+                    let currentAuthoringScope =
+                        let ti = new TokenInfo()
+                        let sink = new AuthoringSink(BackgroundRequestReason.MethodTip, cursor.line-1, cursor.col-1, maxErrors)
+                        let snapshot = VsActual.createTextBuffer(file.CombinedLines).CurrentSnapshot 
+                        let pr = project.Solution.Vs.LanguageService.CreateBackgroundRequest(
+                                                        cursor.line-1, cursor.col-1, ti, file.CombinedLines, snapshot, MethodTipMiscellany.ExplicitlyInvokedViaCtrlShiftSpace,
+                                                        Internal.Utilities.FileSystem.Path.SafeGetFullPath(file.Filename),
+                                                        BackgroundRequestReason.MethodTip, view, sink, null, file.Source.ChangeCount, false)
+                                                   
+                        file.ExecuteBackgroundRequestForScope(pr,canRetryAfterWaiting=true)
+
+                    match currentAuthoringScope with
+                    | null -> 
+                        System.Diagnostics.Debug.Assert(false, "No Authoring Scope was returned by ExecuteBackgroundRequest, even after waiting")
+                        failwith "No Authoring Scope" 
+                    | _ -> 
+                        currentAuthoringScope, origKeyStateAccessor              
+
+                try
+                    let methods = currentAuthoringScope.GetMethodListForAMethodTip(useNameResolutionFallback)
+                    methods 
+                finally
+                    Keyboard.HookGetKeyState origKeyStateAccessor |> ignore
+            member file.GetTokenTypeAtCursor() = 
+                file.EnsureInitiallyFocusedInVs()
+                let line = cursor.line-1 // Cursor is 1-relative
+                let text = lines.[line]
+
+                let colorizer = project.Solution.Vs.GetColorizer(view)
+                let attrs = Array.create text.Length 0u
+                let result = ColorizeLine colorizer line text scanlines.[line] attrs
+                if result <> scanlines.[line+1] then raise (new Exception("Retokenization of same line gave different results."))
+                
+                let tokenColor = (int) (Mask attrs.[cursor.col-1] humanTextAttribute)
+                match tokenColor with
+                    | 0 -> TokenType.Text
+                    | 1 -> TokenType.Keyword
+                    | 2 -> TokenType.Comment
+                    | 3 -> TokenType.Identifier
+                    | 4 -> TokenType.String
+                    | 5 -> TokenType.Number
+                    | 6 -> TokenType.InactiveCode
+                    | 7 -> TokenType.PreprocessorKeyword
+                    | 8 -> TokenType.Operator
+                    | x -> raise (new Exception(sprintf "Unknown token type: %A" x))
+            member file.GetSquigglesAtCursor() =
+                file.EnsureInitiallyFocusedInVs()
+                let IsCursorWithinSpan (cursor:Point) (span:TextSpan) =
+                    let cursor = { line=cursor.line-1; col=cursor.col-1 }  // re-adjust to zero-based
+                    (span.iStartLine < cursor.line || (span.iStartLine = cursor.line && span.iStartIndex <= cursor.col))
+                        && (cursor.line < span.iEndLine || (cursor.line = span.iEndLine && cursor.col <= span.iEndIndex))
+                let errors = (project:>IOpenProject).Errors
+                errors |> List.filter (fun e -> IsCursorWithinSpan cursor e.Context) |> List.map (fun e -> (e.Severity, e.Message))
+                       |> Set.ofList |> Set.toList  // VS ignores duplicates
+            member file.GetSquiggleAtCursor() =
+                match file.GetSquigglesAtCursor() with
+                | [] -> None
+                | h::t -> Some h  // arbitrarily pick one
+            member file.AutoCompleteAtCursorImpl(reason, ?filterText) =
+                let filterText = defaultArg filterText ""
+                let currentAuthoringScope, origKeyStateAccessor = file.DoIntellisenseRequest(reason)
+                
+                try                        
+                    let declarations = 
+                        let snapshot = VsActual.createTextBuffer(file.CombinedLines).CurrentSnapshot 
+                        currentAuthoringScope.GetDeclarations(snapshot, cursor.line-1, cursor.col-1, reason) |> Async.RunSynchronously
+                    match declarations with 
+                    | null -> [||]
+                    | declarations ->
+                        let count = declarations.GetCount(filterText)
+                        let result = Array.zeroCreate count
+                        for i in 0..count-1 do 
+                            let glyph = enum<DeclarationType> (declarations.GetGlyph(filterText,i))
+                            result.[i] <- (declarations.GetDisplayText(filterText,i), declarations.GetName(filterText,i), (fun () -> declarations.GetDescription(filterText,i)), glyph)
+                        result
+                finally
+                    Keyboard.HookGetKeyState origKeyStateAccessor |> ignore
+            member file.AutoCompleteAtCursor(?filterText) = file.AutoCompleteAtCursorImpl(BackgroundRequestReason.MemberSelect, ?filterText=filterText)
+            member file.CompleteAtCursorForReason(reason) = file.AutoCompleteAtCursorImpl(reason)
+            
+            member file.CompletionBestMatchAtCursorFor(text, ?filterText) = 
+                let filterText = defaultArg filterText ""
+                let currentAuthoringScope, origKeyStateAccessor = file.DoIntellisenseRequest(BackgroundRequestReason.MemberSelect)
+                try                        
+                    let declarations = 
+                        let snapshot = VsActual.createTextBuffer(file.CombinedLines).CurrentSnapshot 
+                        currentAuthoringScope.GetDeclarations(snapshot, cursor.line-1,cursor.col-1, BackgroundRequestReason.MemberSelect) |> Async.RunSynchronously
+                    match declarations with 
+                    | null -> None
+                    | declarations -> 
+                        let (index, uniqueMatch, prefixMatch) = declarations.GetBestMatch(filterText, text)
+                        Some (declarations.GetName(filterText,index), uniqueMatch, prefixMatch)
+                finally
+                    Keyboard.HookGetKeyState origKeyStateAccessor |> ignore
+            
+            member file.GotoDefinitionAtCursor (forceGen : bool) =
+              file.EnsureInitiallyFocusedInVs ()
+              let row = cursor.line - 1
+              let col = cursor.col - 1
+              let currentAuthoringScope =
+                  let ti   = new TokenInfo ()
+                  let sink = new AuthoringSink (BackgroundRequestReason.Goto, row, col, maxErrors)
+                  let snapshot = VsActual.createTextBuffer(file.CombinedLines).CurrentSnapshot 
+                  let pr   = project.Solution.Vs.LanguageService.CreateBackgroundRequest(row, col, ti, file.CombinedLines, snapshot, MethodTipMiscellany.Typing, Internal.Utilities.FileSystem.Path.SafeGetFullPath file.Filename, BackgroundRequestReason.Goto, view, sink, null, file.Source.ChangeCount, false)
+                  file.ExecuteBackgroundRequestForScope(pr,canRetryAfterWaiting=true)
+              (currentAuthoringScope :?> FSharpScope).GotoDefinition (view, row, col)
+                 
+            member file.GetF1KeywordAtCursor() =
+              file.EnsureInitiallyFocusedInVs()
+              let row = cursor.line - 1
+              let col = cursor.col - 1
+              let currentAuthoringScope =
+                let ti   = new TokenInfo ()
+                let sink = new AuthoringSink (BackgroundRequestReason.Goto, row, col, maxErrors)
+                let snapshot = VsActual.createTextBuffer(file.CombinedLines).CurrentSnapshot 
+                let pr   = project.Solution.Vs.LanguageService.CreateBackgroundRequest(row, col, ti, file.CombinedLines, snapshot, MethodTipMiscellany.Typing, Internal.Utilities.FileSystem.Path.SafeGetFullPath file.Filename, BackgroundRequestReason.QuickInfo, view, sink, null, file.Source.ChangeCount, false)
+                file.ExecuteBackgroundRequestForScope(pr,canRetryAfterWaiting=true)
+              let keyword = ref None
+              let span = new Microsoft.VisualStudio.TextManager.Interop.TextSpan(iStartIndex=col,iStartLine=row,iEndIndex=col,iEndLine=row)
+              let context = Salsa.VsMocks.Vs.VsUserContext (fun (_,key,value) -> (if key = "keyword" then keyword := Some value); VSConstants.S_OK)
+                
+              currentAuthoringScope.GetF1KeywordString(span, context) 
+              !keyword
+
+            member file.GetNavigationContentAtCursor () =
+              file.EnsureInitiallyFocusedInVs ()
+              let row = cursor.line - 1
+              let col = cursor.col - 1
+              let ti   = new TokenInfo ()
+              let sink = new AuthoringSink (BackgroundRequestReason.FullTypeCheck, row, col, maxErrors)
+              let snapshot = VsActual.createTextBuffer(file.CombinedLines).CurrentSnapshot 
+              let pr   = project.Solution.Vs.LanguageService.CreateBackgroundRequest(row, col, ti, file.CombinedLines, snapshot, MethodTipMiscellany.Typing, Internal.Utilities.FileSystem.Path.SafeGetFullPath file.Filename, BackgroundRequestReason.FullTypeCheck, view, sink, null, file.Source.ChangeCount, false)
+              project.Solution.Vs.LanguageService.ExecuteBackgroundRequest(pr, file.Source) 
+              match project.Solution.Vs.LanguageService.UntypedParseScope with
+              | Some(scope) ->
+                  let typesList = new Collections.ArrayList()
+                  let membersList = new Collections.ArrayList()
+                  let mutable selectedType = 0
+                  let mutable selectedMember = 0
+                  scope.SynchronizeNavigationDropDown(file.Filename, row, col, typesList, membersList, &selectedType, &selectedMember) |> ignore
+                  { TypesAndModules = (typesList.ToArray(typeof<DropDownMember>) :?> DropDownMember[])
+                    Members = (membersList.ToArray(typeof<DropDownMember>) :?> DropDownMember[])
+                    SelectedType = selectedType
+                    SelectedMember = selectedMember }
+              | _ -> 
+                  { TypesAndModules = [| |]; Members = [| |]; SelectedType = -1; SelectedMember = -1 }
+                  
+            member file.GetHiddenRegionCommands() =
+              file.EnsureInitiallyFocusedInVs ()
+              let row = cursor.line - 1
+              let col = cursor.col - 1
+              let ti   = new TokenInfo ()
+              let sink = new AuthoringSink (BackgroundRequestReason.FullTypeCheck, row, col, maxErrors)
+              let snapshot = VsActual.createTextBuffer(file.CombinedLines).CurrentSnapshot 
+              let pr   = project.Solution.Vs.LanguageService.CreateBackgroundRequest(row, col, ti, file.CombinedLines, snapshot, MethodTipMiscellany.Typing, Internal.Utilities.FileSystem.Path.SafeGetFullPath file.Filename, BackgroundRequestReason.FullTypeCheck, view, sink, null, file.Source.ChangeCount, false)
+              project.Solution.Vs.LanguageService.ExecuteBackgroundRequest(pr, file.Source) 
+              match project.Solution.Vs.LanguageService.UntypedParseScope with
+              | Some(scope) ->
+                  scope.GetHiddenRegions(file.Filename)
+              | _ -> 
+
+                  [], Map.empty
+            
+            /// grab a particular line from a file
+            member file.GetLineNumber n =
+              file.EnsureInitiallyFocusedInVs ()
+              lines.[n - 1]
+
+            /// Get full file contents.
+            member file.GetAllLines () = Array.toList lines
+
+            /// get the GotoDefinition-style identifier at a particular location
+            member file.GetIdentifierAtCursor () =
+              file.EnsureInitiallyFocusedInVs ()
+              match QuickParse.GetCompleteIdentifierIsland true lines.[cursor.line - 1] (cursor.col - 1) with
+              | Some (s, col, _) -> Some (s, col)
+              | None -> None
+            
+            member file.ReplaceAllText(replacementLines, takeCoffeeBreak) =
+                file.EnsureInitiallyFocusedInVs()
+                lines <- replacementLines|>List.toArray
+                combinedLines <- null
+                // Update Scanlines. One extra to save the state at the end of the file.
+                scanlines <- Array.create (lines.Length + 1) 0
+                let _, priorbuf = view.GetBuffer()
+                let source = project.Solution.Vs.SourceFactory(priorbuf)
+                // Update View.
+                let projSolution = project.Solution
+                VsMocks.setFileText file.Filename view lines (RecolorizeLines view projSolution.Vs.GetColorizer lines scanlines) (fun line->scanlines.[line])
+                // Scan all lines with the colorizer
+                let _, newbuf = view.GetBuffer()
+                if priorbuf<>newbuf then
+                    project.Solution.Vs.AddSourceForBuffer(newbuf,source)
+                let tcs : IVsTextColorState = downcast box(newbuf)
+                let _ = tcs.ReColorizeLines(0,lines.Length-1)
+                file.Source.RecordChangeToView()
+                // Check the file via OnIdle
+                if takeCoffeeBreak then 
+                    (projSolution.Vs :> IVisualStudio).TakeCoffeeBreak()
+                ()
+               
+            member file.SaveFileToDisk() =
+                file.EnsureInitiallyFocusedInVs()
+                let fullFileName = Path.Combine((project:>IOpenProject).Directory, file.Filename)
+                File.WriteAllLines(fullFileName, lines)               
+                project.Solution.Vs.FileChangeEx.ChangedFile(fullFileName) // Notify clients of IVsFileChangeEx
+                
+                // In Visual Studio, OnAfterFirstDocumentLock is called for "Save" and "Save All"
+                // Model this here. This ultimately causes a ProjectSystem --> LanguageService
+                // "project change" notification which starts the background build for a
+                // project
+                // Product no longer uses RDT, so below is commented out
+                // project.Solution.Vs.LanguageService.OnAfterFirstDocumentLock rdtId 1u 1u
+
+
+            member file.Close () = isClosed <- true
+            interface OpenFile with
+                member file.VS = project.Solution.Vs :> _
+
+                    
+    let MakeMSBuildBehavior = Privates.MakeMSBuildBehavior
+    
+    /// Create a simple Salsa API.
+    let CreateSimple(ops) = 
+        try 
+            if SynchronizationContext.Current = null then
+                let context = new SynchronizationContext() // This executes on the threadpool, but I can't figure out how to get the context for the form.
+                SynchronizationContext.SetSynchronizationContext(context) 
+        
+            let sp,configChangeNotifier = VsMocks.MakeMockServiceProviderAndConfigChangeNotifier()
+        
+            let ls = LanguageServiceState.Create()
+            let rdt = box (VsMocks.createRdt())
+            let tm = box (VsMocks.createTextManager())
+            let getService (serviceType:Type) : obj = 
+                if serviceType = typeof<SVsRunningDocumentTable> then rdt
+                else if serviceType = typeof<SVsTextManager> then tm
+                else raise (new Exception(sprintf "Salsa did not create service %A"  serviceType))
+                
+            let documentationProvider = 
+                { new IdealDocumentationProvider with
+                    override doc.AppendDocumentationFromProcessedXML(appendTo:StringBuilder,processedXml:string,showExceptions, showReturns, paramName) = 
+                        appendTo.AppendLine(processedXml)|> ignore 
+                    override doc.AppendDocumentation(appendTo:StringBuilder,filename:string,signature:string, showExceptions, showReturns, paramName) = 
+                        appendTo.AppendLine(sprintf "[Filename:%s]" filename).AppendLine(sprintf "[Signature:%s]" signature) |> ignore 
+                        if paramName.IsSome then appendTo.AppendLine(sprintf "[ParamName: %s]" paramName.Value) |> ignore
+                } 
+ 
+
+            let vs = Privates.SimpleVisualStudio(configChangeNotifier,sp, ops)
+            Microsoft.FSharp.Compiler.SourceCodeServices.Flags.init()
+            ls.Initialize (ServiceProvider(getService),documentationProvider,VsMocks.createLanguagePreferences(),true,vs.SourceFactory)
+            vs.LanguageService <- ls
+            vs :> VisualStudio
+        with e -> 
+            // Need to just print the error because NUnit has not fully initialized the exception at this point.
+            printf "Error in createSimple: %A" e
+            reraise() 
+    
+    // ------------------------------------------------------------------------------
+    
+    /// The different variations of of Salsa tests    
+    module Models = 
+        let VsSimpl(vs:VisualStudio) = vs :?> Privates.SimpleVisualStudio
+        let VsImpl(vs:VisualStudio)         = vs :?> IVisualStudio
+        let SolutionImpl(sol:OpenSolution)  = sol :?> IOpenSolution
+        let ProjectImpl(proj:OpenProject)   = proj :?> IOpenProject
+        let OpenFileSimpl(openfile:OpenFile)   = openfile :?> Privates.SimpleOpenFile
+        let FileSimpl(file:File) = file :?> Privates.SimpleFile
+
+        /// Salsa tests which create .fsproj files for projects.
+        let MSBuildWithFlavor(behaviorHooks) = 
+            let rec ops = 
+                { CreateVisualStudio                    = fun() -> CreateSimple(ops)
+                  CreateSolution                        = fun vs -> VsImpl(vs).CreateSolution()
+                  GetOutputWindowPaneLines              = fun vs -> VsSimpl(vs).GetOutputWindowPaneLines()
+                  CloseSolution                         = fun (solution) -> SolutionImpl(solution).Close()
+                  CreateProject                         = fun (solution,projectBaseName) -> SolutionImpl(solution).CreateProjectFlavor behaviorHooks projectBaseName
+                  CreateProjectWithHooks                = fun (solution,hooks,projectBaseName) -> SolutionImpl(solution).CreateProjectFlavor hooks projectBaseName
+                  NewFile                               = fun (vs,filename,buildAction,lines) -> VsSimpl(vs).NewFile(filename,buildAction,lines,behaviorHooks)
+                  DeleteFileFromDisk = fun (file:File) -> FileSimpl(file).DeleteFileFromDisk()
+                  AddFileFromText                       = fun (project:OpenProject,filenameOnDisk,filenameInProject,buildAction,lines) -> ProjectImpl(project).AddFileFromText(filenameOnDisk,filenameInProject,buildAction,lines)
+                  AddLinkedFileFromText                 = fun (project:OpenProject,filenameOnDisk,includeFilenameInProject,linkFilenameInProject,buildAction,lines)->ProjectImpl(project).AddLinkedFileFromText(filenameOnDisk,includeFilenameInProject,linkFilenameInProject,buildAction,lines)
+                  AddAssemblyReference                  = fun (project,reference,specificVersion) -> ProjectImpl(project).AddAssemblyReference(reference,specificVersion)
+                  AddProjectReference                   = fun (project1,project2) -> ProjectImpl(project1).AddProjectReference(project2)
+                  ProjectDirectory                      = fun project -> ProjectImpl(project).Directory            
+                  ProjectFile                           = fun project -> ProjectImpl(project).ProjectFile
+                  SetVersionFile                        = fun (project,file) -> ProjectImpl(project).SetVersionFile(file)
+                  SetOtherFlags                         = fun (project,flags) -> ProjectImpl(project).SetOtherFlags(flags)
+                  SetConfigurationAndPlatform           = fun (project,configAndPlatform) -> ProjectImpl(project).ConfigurationAndPlatform <- configAndPlatform
+                  AddDisabledWarning                    = fun (project,code) -> ProjectImpl(project).AddDisabledWarning(code)
+                  GetErrors                             = fun project -> ProjectImpl(project).Errors
+                  BuildProject                          = fun (project,target) -> ProjectImpl(project).Build(target)
+                  GetMainOutputAssembly                 = fun project -> ProjectImpl(project).GetMainOutputAssembly()
+                  SaveProject                           = fun project->ProjectImpl(project).Save()                
+                  OpenFileViaOpenFile                   = fun (vs,filename) -> VsSimpl(vs).OpenFileViaOpenFile(filename,behaviorHooks)
+                  OpenFile                              = fun (project,filename) -> ProjectImpl(project).OpenFile(filename)
+                  SetProjectDefines                     = fun (project,defines) -> ProjectImpl(project).SetProjectDefines(defines)
+                  PlaceIntoProjectFileBeforeImport      = fun (project,xml) -> ProjectImpl(project).PlaceIntoProjectFileBeforeImport(xml)
+                  GetOpenFiles                          = fun project -> ProjectImpl(project).GetOpenFiles()
+                  MoveCursorTo                          = fun (file,line,col) -> OpenFileSimpl(file).MoveCursorTo(line,col)
+                  GetCursorLocation                     = fun (file) -> OpenFileSimpl(file).GetCursorLocation()
+                  OpenExistingProject                   = fun (vs,dir,projname) -> VsImpl(vs).OpenExistingProject behaviorHooks dir projname
+                  MoveCursorToEndOfMarker               = fun (file,marker) -> OpenFileSimpl(file).MoveCursorToEndOfMarker(marker)
+                  MoveCursorToStartOfMarker             = fun (file,marker) -> OpenFileSimpl(file).MoveCursorToStartOfMarker(marker)
+                  GetNameOfOpenFile                     = fun (file) -> OpenFileSimpl(file).GetFileName()
+                  GetCheckOptionsOfScript               = fun (file) -> OpenFileSimpl(file).GetCheckOptionsOfScript()
+                  GetQuickInfoAtCursor                  = fun file -> OpenFileSimpl(file).GetQuickInfoAtCursor()
+                  GetQuickInfoAndSpanAtCursor           = fun file -> OpenFileSimpl(file).GetQuickInfoAndSpanAtCursor()
+                  GetMatchingBracesForPositionAtCursor  = fun file -> OpenFileSimpl(file).GetMatchingBracesForPositionAtCursor()
+                  GetParameterInfoAtCursor              = fun file -> OpenFileSimpl(file).GetParameterInfoAtCursor(true)
+                  GetParameterInfoAtCursorNoFallback    = fun file -> OpenFileSimpl(file).GetParameterInfoAtCursor(false)
+                  GetTokenTypeAtCursor                  = fun file -> OpenFileSimpl(file).GetTokenTypeAtCursor()
+                  GetSquiggleAtCursor                   = fun file -> OpenFileSimpl(file).GetSquiggleAtCursor()
+                  GetSquigglesAtCursor                  = fun file -> OpenFileSimpl(file).GetSquigglesAtCursor()
+                  AutoCompleteAtCursor                  = fun file -> OpenFileSimpl(file).AutoCompleteAtCursor()
+                  CompleteAtCursorForReason             = fun (file,reason) -> OpenFileSimpl(file).CompleteAtCursorForReason(reason)
+                  CompletionBestMatchAtCursorFor        = fun (file, value, filterText) -> (OpenFileSimpl(file)).CompletionBestMatchAtCursorFor(value, ?filterText=filterText)
+                  GotoDefinitionAtCursor                = fun file forceGen -> (OpenFileSimpl file).GotoDefinitionAtCursor forceGen
+                  GetNavigationContentAtCursor          = fun file -> OpenFileSimpl(file).GetNavigationContentAtCursor()
+                  GetHiddenRegionCommands               = fun file -> OpenFileSimpl(file).GetHiddenRegionCommands()
+                  GetIdentifierAtCursor                 = fun file -> OpenFileSimpl(file).GetIdentifierAtCursor ()
+                  GetF1KeywordAtCursor                  = fun file -> OpenFileSimpl(file).GetF1KeywordAtCursor ()
+                  GetLineNumber                         = fun file n -> OpenFileSimpl(file).GetLineNumber n
+                  GetAllLines                           = fun file -> (OpenFileSimpl file).GetAllLines ()
+                  SwitchToFile                          = fun (vs,file) -> VsSimpl(vs).FocusOpenFile(OpenFileSimpl(file))
+                  OnIdle                                = fun vs -> VsImpl(vs).OnIdle()
+                  ShiftKeyDown                          = fun vs -> VsImpl(vs).ShiftKeyDown()
+                  ShiftKeyUp                            = fun vs -> VsImpl(vs).ShiftKeyUp()
+                  TakeCoffeeBreak                       = fun vs -> VsImpl(vs).TakeCoffeeBreak() 
+                  ReplaceFileInMemory                   = fun (file,contents,takeCoffeeBreak) -> OpenFileSimpl(file).ReplaceAllText(contents, takeCoffeeBreak)
+                  SaveFileToDisk                        = fun file -> OpenFileSimpl(file).SaveFileToDisk()
+                  CreatePhysicalProjectFileInMemory     = Privates.CreateMsBuildProjectText false
+                  CleanUp                               = fun vs -> VsImpl(vs).CleanUp()
+                  ClearLanguageServiceRootCachesAndCollectAndFinalizeAllTransients                   = fun vs -> VsImpl(vs).ClearLanguageServiceRootCachesAndCollectAndFinalizeAllTransients()
+                  AutoCompleteMemberDataTipsThrowsScope = fun (message) -> 
+                                                              let Hook(callback) : Microsoft.FSharp.Compiler.SourceCodeServices.DataTipElement =                                                               
+                                                                  let exn = Microsoft.FSharp.Compiler.ErrorLogger.Error((0,message),range.Zero)
+                                                                  let ph = Microsoft.FSharp.Compiler.ErrorLogger.PhasedError.Create(exn, 
+                                                                                        Microsoft.FSharp.Compiler.ErrorLogger.BuildPhase.TypeCheck)
+                                                                  Microsoft.FSharp.Compiler.ErrorLogger.phasedError (ph)
+                                                              Microsoft.FSharp.Compiler.SourceCodeServices.TestHooks.FormatOverloadsToListScope(Hook)
+                  OutOfConeFilesAreAddedAsLinks         = false                
+                  SupportsOutputWindowPane = false
+                  CleanInvisibleProject                 = fun vs -> VsImpl(vs).CleanInvisibleProject()
+                }
+            ops, behaviorHooks
+            
+        /// Salsa tests which create .fsproj files for projects.
+        let MSBuild() = 
+            let behaviorHooks = MakeMSBuildBehavior()
+            MSBuildWithFlavor(behaviorHooks)
+            
+        /// Salsa tests which create .fsproj files using the installed version of
+        /// FSharp.targets.
+        let InstalledMSBuild() = 
+            // Overwrite the default MSBuildBehavior hooks to use the installed
+            // FSharp.targets file.
+            let behaviorHooks = 
+                { MakeMSBuildBehavior() with
+                    CreateProjectHook = Privates.CreateMsBuildProject true }
+
+            // Same here - use installed version of FSharp.targets            
+            let ops, flavor = MSBuildWithFlavor(behaviorHooks)
+            let updatedOps = 
+                { ops with 
+                    CreatePhysicalProjectFileInMemory = Privates.CreateMsBuildProjectText true }
+            (updatedOps, flavor)
diff --git a/vsintegration/src/Salsa/salsa.fsi b/vsintegration/src/Salsa/salsa.fsi
new file mode 100644
index 0000000..14a4893
--- /dev/null
+++ b/vsintegration/src/Salsa/salsa.fsi
@@ -0,0 +1,222 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+namespace Salsa
+
+open Microsoft.VisualStudio
+open Microsoft.VisualStudio.Shell.Interop
+open Microsoft.VisualStudio.FSharp.ProjectSystem
+open Microsoft.VisualStudio.FSharp.LanguageService
+open Microsoft.VisualStudio.TextManager.Interop
+
+open Microsoft.Build.Framework
+open Microsoft.VisualStudio.FSharp.LanguageService.Implementation
+
+module internal Salsa = 
+    
+    [<Class>]
+    type HostCompile = 
+        interface ITaskHost 
+        member Compile : System.Converter<int,int> * string[] * string[] -> int
+        
+    
+    type TokenType = Text | Keyword | Comment | Identifier | String | Number | InactiveCode | PreprocessorKeyword | Operator
+    
+    /// Declaration types.
+    type DeclarationType = 
+        | Class         = 0
+        | Constant      = 6
+        | FunctionType  = 12            // Like 'type FunctionType=unit->unit' 
+        | Enum          = 18
+        | EnumMember    = 24
+        | Event         = 30
+        | Exception     = 36
+        | Interface     = 48
+        | Method        = 72
+        | FunctionValue = 74            // Like 'type Function x = 0'
+        | Module        = 84
+        | Namespace     = 90
+        | Property      = 102
+        | ValueType     = 108           // Like 'type ValueType=int*int' 
+        | RareType      = 120           // Bucket for unusual types like 'type AsmType = (# "!0[]" #)'
+        | Record        = 126
+        | DiscriminatedUnion = 132 
+        
+    type BuildAction =
+        | Compile = 0
+        | EmbeddedResource = 1
+        | None = 2        
+        
+    type BuildResult = {
+        ExecutableOutput : string
+        BuildSucceeded : bool
+    }
+    
+    /// An error
+    [<Sealed>]
+    type Error  = 
+        member Path : string
+        member Message : string
+        member Context : TextSpan
+        member Severity : Severity
+        override ToString : unit -> string
+    
+
+
+    type ChangeCallBack = IVsHierarchy * string -> unit
+
+    /// Hooks for controlling behaviors
+    
+    
+    /// Thrown when a marker is not found when placing the cursor via VsOps
+    exception MarkerNotFoundException of string
+    
+    /// Representation of an item from the completion list
+    type CompletionItem = string * string * (unit -> string) * DeclarationType
+    
+    type GotoDefnResult = Microsoft.VisualStudio.FSharp.LanguageService.GotoDefinitionResult
+    [<AutoOpen>]
+    module GotoDefnResultExtensions = 
+        type Microsoft.VisualStudio.FSharp.LanguageService.GotoDefinitionResult with
+            member ToOption : unit -> (TextSpan * string) option
+
+    /// Representes the information that is displayed in the navigation bar
+    type NavigationBarResult = 
+      { TypesAndModules : DropDownMember[]
+        Members : DropDownMember[]
+        SelectedType : int
+        SelectedMember : int }
+    
+    /// Methods for simulating VisualStudio
+    [<NoEquality; NoComparison>]
+    type ProjectBehaviorHooks = {
+        CreateProjectHook:  (*projectFilename:*)string ->
+                            (*files:*)(string*BuildAction*string option) list ->
+                            (*references:*)(string*bool) list ->
+                            (*projReferences:*)string list ->
+                            (*disabledWarnings:*)string list ->
+                            (*defines*)string list ->
+                            (*versionFile:*)string ->
+                            (*otherFlags:*)string ->
+                            (*preImportXml:*)string ->
+                            (*targetFrameworkVersion:*)string -> unit
+        InitializeProjectHook : OpenProject -> unit
+        MakeHierarchyHook : string->string->string->ChangeCallBack->OleServiceProvider->IVsHierarchy
+        AddFileToHierarchyHook : string -> IVsHierarchy -> unit
+        BuildHook : (*basename:*)string -> (*target:*)string -> IVsOutputWindowPane -> BuildResult
+        GetMainOutputAssemblyHook : string -> string
+        SaveHook : unit -> unit
+        DestroyHook : unit->unit
+        ModifyConfigurationAndPlatformHook : string->unit
+    }   
+    and [<NoEquality; NoComparison>] VsOps = {
+        CreateVisualStudio                : unit -> VisualStudio
+        CreateSolution                    : VisualStudio -> OpenSolution
+        GetOutputWindowPaneLines          : VisualStudio -> string list
+        CloseSolution                     : OpenSolution ->unit
+        CreateProject                     : OpenSolution * string -> OpenProject
+        CreateProjectWithHooks            : OpenSolution * ProjectBehaviorHooks * string -> OpenProject
+        NewFile                           : VisualStudio * string * BuildAction * string list -> File
+        DeleteFileFromDisk : File -> unit
+        AddFileFromText                   : OpenProject * string * string * BuildAction * string list -> File
+        AddLinkedFileFromText             : OpenProject*string*string*string*BuildAction*string list->File
+        AddAssemblyReference              : OpenProject * string * bool -> unit 
+        AddProjectReference               : OpenProject * OpenProject -> unit 
+        ProjectDirectory                  : OpenProject -> string
+        ProjectFile                       : OpenProject -> string
+        SetVersionFile                    : OpenProject * string -> unit
+        SetOtherFlags                     : OpenProject * string -> unit
+        SetConfigurationAndPlatform       : OpenProject * string -> unit
+        AddDisabledWarning                : OpenProject * string -> unit
+        GetErrors                         : OpenProject -> Error list 
+        BuildProject                      : OpenProject * string -> BuildResult 
+        GetMainOutputAssembly             : OpenProject -> string
+        SaveProject                       : OpenProject -> unit        
+        OpenFileViaOpenFile               : VisualStudio * string -> OpenFile
+        OpenFile                          : OpenProject * string -> OpenFile 
+        GetOpenFiles                      : OpenProject -> OpenFile list
+        SetProjectDefines                 : OpenProject * string list -> unit
+        PlaceIntoProjectFileBeforeImport  : OpenProject * string -> unit
+        OpenExistingProject               : VisualStudio * string * string -> OpenProject * OpenSolution
+        MoveCursorTo                      : OpenFile * int * int -> unit
+        GetCursorLocation                 : OpenFile -> int * int
+        GetLineNumber                     : OpenFile -> int -> string
+        GetAllLines                       : OpenFile -> string list
+        SwitchToFile                      : VisualStudio * OpenFile -> unit
+        OnIdle                            : VisualStudio -> unit
+        ShiftKeyDown                      : VisualStudio -> unit
+        ShiftKeyUp                        : VisualStudio -> unit
+        TakeCoffeeBreak                   : VisualStudio -> unit 
+        ReplaceFileInMemory               : OpenFile * string list * bool -> unit
+        SaveFileToDisk                    : OpenFile -> unit
+        CleanUp                           : VisualStudio -> unit
+        CleanInvisibleProject             : VisualStudio -> unit
+        ClearLanguageServiceRootCachesAndCollectAndFinalizeAllTransients : VisualStudio -> unit
+        GetSquiggleAtCursor               : OpenFile -> (Microsoft.VisualStudio.FSharp.LanguageService.Severity * string) option
+        GetSquigglesAtCursor              : OpenFile -> (Microsoft.VisualStudio.FSharp.LanguageService.Severity * string) list
+        /// does a BackgroundRequestReason.MemberSelect at the cursor
+        AutoCompleteAtCursor              : OpenFile -> CompletionItem array
+        /// like AutoCompleteAtCursor, but can pass e.g. BackgroundRequestReason.CompleteWord to do Ctrl-space rather than auto-dot-popup-completion
+        CompleteAtCursorForReason         : OpenFile * Microsoft.VisualStudio.FSharp.LanguageService.BackgroundRequestReason -> CompletionItem array
+        CompletionBestMatchAtCursorFor    : OpenFile * string * string option -> (string * bool * bool) option
+        MoveCursorToEndOfMarker           : OpenFile * string -> unit
+        MoveCursorToStartOfMarker         : OpenFile * string -> unit
+        GetQuickInfoAtCursor              : OpenFile -> string  
+        GetQuickInfoAndSpanAtCursor       : OpenFile -> string*TextSpan
+        GetMatchingBracesForPositionAtCursor : OpenFile -> (TextSpan * TextSpan) array
+        GetNameOfOpenFile                 : OpenFile -> string
+        GetCheckOptionsOfScript           : OpenFile -> Microsoft.FSharp.Compiler.SourceCodeServices.CheckOptions
+        GetParameterInfoAtCursor          : OpenFile -> MethodListForAMethodTip
+        GetParameterInfoAtCursorNoFallback: OpenFile -> MethodListForAMethodTip
+        GetTokenTypeAtCursor              : OpenFile -> TokenType
+        GetIdentifierAtCursor             : OpenFile -> (string * int) option
+        GetF1KeywordAtCursor              : OpenFile -> string option
+        GotoDefinitionAtCursor            : OpenFile -> bool -> GotoDefnResult
+        GetNavigationContentAtCursor      : OpenFile -> NavigationBarResult
+        GetHiddenRegionCommands           : OpenFile -> list<NewHiddenRegion> * Map<uint32, TextSpan>
+        CreatePhysicalProjectFileInMemory : ((*files:*)(string*BuildAction*string option) list) ->
+                                            ((*references:*)(string*bool) list) ->
+                                            ((*projectReferences:*)string list) ->
+                                            ((*disabledWarnings:*)string list) ->
+                                            ((*defines:*)string list) ->
+                                            (*versionFile*) string ->
+                                            ((*otherFlags:*)string) ->
+                                            ((*otherProjMisc:*)string) -> 
+                                            ((*targetFrameworkVersion:*)string) -> string
+                
+        /// True if files outside of the project cone are added as links.
+        AutoCompleteMemberDataTipsThrowsScope : string -> System.IDisposable
+        
+        // VsOps capabilities.
+        OutOfConeFilesAreAddedAsLinks : bool
+        SupportsOutputWindowPane : bool   
+    }
+
+    // Opaque handles to vs objects
+    /// Simulate a VisualStudio instance
+    and VisualStudio = interface 
+        abstract VsOps : VsOps
+    end
+    /// The solution opened in VS
+    and OpenSolution = interface 
+        abstract VS : VisualStudio
+    end
+    /// A project opened in VS
+    and OpenProject = interface 
+        abstract VS : VisualStudio
+    end
+    /// A file opened in VS
+    and OpenFile = interface 
+        abstract VS : VisualStudio
+    end
+    /// A file on disk
+    and File = interface end    
+    
+    val CreateFSharpManifestResourceName : projectFileName:string -> configuration:string -> platform:string -> (string * string) list
+
+    /// The different variations of of Salsa tests    
+    module Models = 
+        /// Salsa tests which create .fsproj files for projects.
+        val MSBuild : unit -> VsOps * ProjectBehaviorHooks
+        /// Salsa tests which create .fsproj files for projects using the installed
+        /// FSharp.targets file.
+        val InstalledMSBuild : unit -> VsOps * ProjectBehaviorHooks
diff --git a/vsintegration/src/unittests/Resources.MockTypeProviders/DefinitionLocationAttribute/ArtificalEventInfo.cs b/vsintegration/src/unittests/Resources.MockTypeProviders/DefinitionLocationAttribute/ArtificalEventInfo.cs
new file mode 100644
index 0000000..50b6df2
--- /dev/null
+++ b/vsintegration/src/unittests/Resources.MockTypeProviders/DefinitionLocationAttribute/ArtificalEventInfo.cs
@@ -0,0 +1,120 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Reflection;
+using Microsoft.FSharp.Core.CompilerServices;
+
+namespace TypeProviderInCSharp
+{
+    class ArtificalEventInfo : EventInfo
+    {
+        string _Name;
+        Type _DeclaringType;
+        Type _EventHandleType;
+        MethodInfo _AddMethod;
+        MethodInfo _RemoveMethod;
+
+        public ArtificalEventInfo(string Name, Type DeclaringType, Type EventHandleType)
+        {
+            _Name = Name;
+            _DeclaringType = DeclaringType;
+            _EventHandleType = EventHandleType;
+
+            _AddMethod = new ArtificialMethodInfo("add_" + _Name, _DeclaringType, typeof(void), MethodAttributes.FamANDAssem | MethodAttributes.Family | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.Public);
+            _RemoveMethod = new ArtificialMethodInfo("remove_" + _Name, _DeclaringType, typeof(void), MethodAttributes.FamANDAssem | MethodAttributes.Family | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.Public);
+        }
+
+        // This one is invoked
+        public override Type EventHandlerType
+        {
+            get
+            {
+                return _EventHandleType;
+            }
+        }
+
+        public override string Name
+        {
+            get 
+            { 
+                return _Name;
+            }
+        }
+
+        public override Type DeclaringType
+        {
+            get
+            {
+                return _DeclaringType;
+            }
+        }
+
+        // This one is needed
+        public override MethodInfo GetAddMethod(bool nonPublic)
+        {
+            Debug.Assert(!nonPublic, "GetAddMethod() was called with nonPublic=true");
+            return _AddMethod;
+        }
+
+        // This one is needed
+        public override MethodInfo GetRemoveMethod(bool nonPublic)
+        {
+            Debug.Assert(!nonPublic, "GetRemoveMethod() was called with nonPublic=true");
+            return _RemoveMethod;
+        }
+
+        public override object[] GetCustomAttributes(Type attributeType, bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        public override EventAttributes Attributes
+        {
+            get
+            {
+                return EventAttributes.None;
+            }
+        }
+
+        public override MethodInfo GetRaiseMethod(bool nonPublic)
+        {
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override object[] GetCustomAttributes(bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        public override bool IsDefined(Type attributeType, bool inherit)
+        {
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override Type ReflectedType
+        {
+            get
+            {
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override IList<CustomAttributeData> GetCustomAttributesData()
+        {
+            var attrs = new List<CustomAttributeData>();
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderXmlDocAttribute(string.Format("This is a synthetic *event* created by me for {0}.{1}", this._DeclaringType.Namespace, this._DeclaringType.Name))));
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderDefinitionLocationAttribute() { Column = 21, FilePath = "File.fs", Line = 4 }));
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderEditorHideMethodsAttribute()));
+            return attrs;
+        }
+    }
+}
diff --git a/vsintegration/src/unittests/Resources.MockTypeProviders/DefinitionLocationAttribute/ArtificialConstructorInfo.cs b/vsintegration/src/unittests/Resources.MockTypeProviders/DefinitionLocationAttribute/ArtificialConstructorInfo.cs
new file mode 100644
index 0000000..5a50f20
--- /dev/null
+++ b/vsintegration/src/unittests/Resources.MockTypeProviders/DefinitionLocationAttribute/ArtificialConstructorInfo.cs
@@ -0,0 +1,124 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Reflection;
+using Microsoft.FSharp.Core.CompilerServices;
+
+namespace TypeProviderInCSharp
+{
+    class ArtificialConstructorInfo : ConstructorInfo
+    {
+        Type _DeclaringType;
+        ParameterInfo[] _ParameterInfo;
+
+        public ArtificialConstructorInfo(Type DeclaringType, ParameterInfo[] ParamInfo)
+        {
+            _DeclaringType = DeclaringType;
+            _ParameterInfo = ParamInfo;
+        }
+
+        public override Type DeclaringType
+        {
+            get
+            {
+                return _DeclaringType;
+            }
+        }
+
+        // This one is invoked
+        public override ParameterInfo[] GetParameters()
+        {
+            return _ParameterInfo;
+        }
+
+        // This one is indeed invoked
+        // I believe we should always return ".ctor"
+        public override string Name
+        {
+            get
+            {
+                return ".ctor";
+            }
+        }
+
+        // Does it matter what we return here?
+        // This property is definitely checked by the compiler in code like this:
+        // let _ = new N.T()
+        // I copied the attribute set from the .ctor of System.DateTime - the documentation on MSDN assumes that one is already familiar with
+        // what they mean (=totally useless, as often happens)
+        public override MethodAttributes Attributes
+        {
+            get
+            {
+                return MethodAttributes.FamANDAssem | MethodAttributes.Family | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName;
+            }
+        }
+
+        public override object[] GetCustomAttributes(Type attributeType, bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        public override object Invoke(BindingFlags invokeAttr, Binder binder, object[] parameters, System.Globalization.CultureInfo culture)
+        {
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override MethodImplAttributes GetMethodImplementationFlags()
+        {
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override object Invoke(object obj, BindingFlags invokeAttr, Binder binder, object[] parameters, System.Globalization.CultureInfo culture)
+        {
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override RuntimeMethodHandle MethodHandle
+        {
+            get
+            {
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override object[] GetCustomAttributes(bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        public override bool IsDefined(Type attributeType, bool inherit)
+        {
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override Type ReflectedType
+        {
+            get
+            {
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override IList<CustomAttributeData> GetCustomAttributesData()
+        {
+            var attrs = new List<CustomAttributeData>();
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderXmlDocAttribute(string.Format("This is a synthetic .ctor created by me for {0}.{1}", this._DeclaringType.Namespace, this._DeclaringType.Name))));
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderDefinitionLocationAttribute() { Column = 21, FilePath = "File.fs", Line = 3 }));
+            // attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderEditorHideMethodsAttribute()));
+            return attrs;
+        }
+    }
+}
diff --git a/vsintegration/src/unittests/Resources.MockTypeProviders/DefinitionLocationAttribute/ArtificialMethodInfo.cs b/vsintegration/src/unittests/Resources.MockTypeProviders/DefinitionLocationAttribute/ArtificialMethodInfo.cs
new file mode 100644
index 0000000..96bb3f9
--- /dev/null
+++ b/vsintegration/src/unittests/Resources.MockTypeProviders/DefinitionLocationAttribute/ArtificialMethodInfo.cs
@@ -0,0 +1,152 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Reflection;
+using Microsoft.FSharp.Core.CompilerServices;
+
+namespace TypeProviderInCSharp
+{
+    class ArtificialMethodInfo : MethodInfo
+    {
+        string _Name;
+        Type _DeclaringType;
+        Type _ReturnType;
+        MethodAttributes _MethodAttributes;
+
+        public ArtificialMethodInfo(string Name, Type DeclaringType, Type ReturnType, MethodAttributes MethodAttributes)
+        {
+            _Name = Name;
+            _DeclaringType = DeclaringType;
+            _ReturnType = ReturnType;
+            _MethodAttributes = MethodAttributes;
+        }
+
+        public override string Name
+        {
+            get 
+            { 
+                return _Name;
+            }
+        }
+
+        public override Type DeclaringType
+        {
+            get
+            {
+                return _DeclaringType;
+            }
+        }
+
+        // Make the method Public and Static - 
+        // TODO: should be configurable in the ctor...
+        public override MethodAttributes Attributes
+        {
+            get
+            {
+                return _MethodAttributes;
+            }
+        }
+
+        // No params
+        // TODO: should be configurable in the ctor...
+        public override ParameterInfo[] GetParameters()
+        {
+            return new ParameterInfo[] {  };
+        }
+
+        public override ParameterInfo ReturnParameter
+        {
+            get
+            {
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+
+            }
+        }
+
+        public override Type ReturnType
+        {
+            get
+            {
+                return _ReturnType;
+            }
+        }
+
+        public override MethodInfo GetBaseDefinition()
+        {
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override ICustomAttributeProvider ReturnTypeCustomAttributes
+        {
+            get 
+            {
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override MethodImplAttributes GetMethodImplementationFlags()
+        {
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override object Invoke(object obj, BindingFlags invokeAttr, Binder binder, object[] parameters, System.Globalization.CultureInfo culture)
+        {
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override RuntimeMethodHandle MethodHandle
+        {
+            get 
+            {
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override object[] GetCustomAttributes(Type attributeType, bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        public override object[] GetCustomAttributes(bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        public override bool IsDefined(Type attributeType, bool inherit)
+        {
+            Debug.Assert(false, "NYI"); 
+            throw new NotImplementedException();
+        }
+
+        public override Type ReflectedType
+        {
+            get 
+            { 
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override IList<CustomAttributeData> GetCustomAttributesData()
+        {
+            var attrs = new List<CustomAttributeData>();
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderXmlDocAttribute("This is a synthetic *method* created by me!!")));
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderDefinitionLocationAttribute() { Column = 21, FilePath = "File.fs", Line = 3 }));
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderEditorHideMethodsAttribute()));
+            return attrs;
+        }
+
+    }
+}
diff --git a/vsintegration/src/unittests/Resources.MockTypeProviders/DefinitionLocationAttribute/ArtificialParamInfo.cs b/vsintegration/src/unittests/Resources.MockTypeProviders/DefinitionLocationAttribute/ArtificialParamInfo.cs
new file mode 100644
index 0000000..15b3b86
--- /dev/null
+++ b/vsintegration/src/unittests/Resources.MockTypeProviders/DefinitionLocationAttribute/ArtificialParamInfo.cs
@@ -0,0 +1,144 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Reflection;
+using Microsoft.FSharp.Core.CompilerServices;
+
+namespace TypeProviderInCSharp
+{
+    public class ArtificialParamInfo : ParameterInfo
+    {
+        Type _type;
+        bool _isRetVal;
+
+        public ArtificialParamInfo(Type type, bool isRetVal)
+        {
+            _type = type;
+            _isRetVal = IsRetval;
+        }
+
+        // TODO: allow more customizations...
+        public override ParameterAttributes Attributes
+        {
+            get
+            {
+                return _isRetVal ? ParameterAttributes.Retval : ParameterAttributes.None;
+            }
+        }
+
+        public override Type ParameterType
+        {
+            get
+            {
+                return _type;
+            }
+        }
+
+        public override object DefaultValue
+        {
+            get
+            {
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override bool Equals(object obj)
+        {
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override object[] GetCustomAttributes(bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        public override object[] GetCustomAttributes(Type attributeType, bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        public override int GetHashCode()
+        {
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override Type[] GetOptionalCustomModifiers()
+        {
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override Type[] GetRequiredCustomModifiers()
+        {
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override bool IsDefined(Type attributeType, bool inherit)
+        {
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override MemberInfo Member
+        {
+            get
+            {
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override int MetadataToken
+        {
+            get
+            {
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override string Name
+        {
+            get
+            {
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override int Position
+        {
+            get
+            {
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override object RawDefaultValue
+        {
+            get
+            {
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override string ToString()
+        {
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+    }
+
+}
diff --git a/vsintegration/src/unittests/Resources.MockTypeProviders/DefinitionLocationAttribute/ArtificialPropertyInfo.cs b/vsintegration/src/unittests/Resources.MockTypeProviders/DefinitionLocationAttribute/ArtificialPropertyInfo.cs
new file mode 100644
index 0000000..c93af60
--- /dev/null
+++ b/vsintegration/src/unittests/Resources.MockTypeProviders/DefinitionLocationAttribute/ArtificialPropertyInfo.cs
@@ -0,0 +1,166 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Reflection;
+using Microsoft.FSharp.Core.CompilerServices;
+
+namespace TypeProviderInCSharp
+{
+    class ArtificialPropertyInfo : PropertyInfo
+    {
+        string _Name;
+        bool _CanRead;
+        bool _CanWrite;
+        Type _DeclaringType;
+        Type _PropertyType;
+
+        MethodInfo _GetMethod;
+        MethodInfo _SetMethod;
+
+        public ArtificialPropertyInfo(string Name, Type DeclaringType, Type PropertyType, bool CanRead, bool CanWrite)
+        {
+            _Name = Name;
+            _DeclaringType = DeclaringType;
+            _PropertyType = PropertyType;
+            _CanRead = CanRead;
+            _CanWrite = CanWrite;
+
+            if(CanRead)
+                _GetMethod = new ArtificialMethodInfo("get_" + _Name, _DeclaringType, _PropertyType, MethodAttributes.Public | MethodAttributes.Static);
+            if (CanWrite)
+                _SetMethod = new ArtificialMethodInfo("set_" + _Name, _DeclaringType, null /* ?? */, MethodAttributes.Public | MethodAttributes.Static);
+
+        }
+
+        // The name of this property...
+        public override string Name
+        {
+            get
+            {
+                return _Name;
+            }
+        }
+
+        // Needed
+        public override bool CanRead
+        {
+            get
+            {
+                return _CanRead;
+            }
+        }
+
+        // If CanRead is true, this one gets invoked.
+        public override MethodInfo GetGetMethod(bool nonPublic)
+        {
+            Debug.Assert(!nonPublic, "GetGetMethod was invoked with nonPublic=true");
+            return _GetMethod;
+        }
+
+        // Why is this invoked?
+        public override ParameterInfo[] GetIndexParameters()
+        {
+            return new ParameterInfo[] { /* new ArtificialParamInfo(typeof(int), isRetVal: false), new ArtificialParamInfo(typeof(decimal), isRetVal: false) */};
+        }
+
+        // If CanRead is false, this one gets invoked... without checking 'CanWrite' (?)
+        public override MethodInfo GetSetMethod(bool nonPublic)
+        {
+            return _SetMethod;
+        }
+
+        public override bool CanWrite
+        {
+            get
+            {
+                return _CanWrite;
+            }
+        }
+
+        // Interestingly enough, this one seems to be invoked only when I hover over the property in the IDE...
+        public override Type PropertyType
+        {
+            get
+            {
+                return _PropertyType;
+            }
+        }
+
+        // Interestingly enough, this one seems to be invoked only when I hover over the property in the IDE...
+        public override Type DeclaringType
+        {
+            get
+            {
+                return _DeclaringType;
+            }
+        }
+
+        public override object[] GetCustomAttributes(Type attributeType, bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        public override PropertyAttributes Attributes
+        {
+            get
+            {
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override MethodInfo[] GetAccessors(bool nonPublic)
+        {
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override object GetValue(object obj, BindingFlags invokeAttr, Binder binder, object[] index, System.Globalization.CultureInfo culture)
+        {
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override void SetValue(object obj, object value, BindingFlags invokeAttr, Binder binder, object[] index, System.Globalization.CultureInfo culture)
+        {
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override object[] GetCustomAttributes(bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        public override bool IsDefined(Type attributeType, bool inherit)
+        {
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override Type ReflectedType
+        {
+            get
+            {
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override IList<CustomAttributeData> GetCustomAttributesData()
+        {
+            var attrs = new List<CustomAttributeData>();
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderXmlDocAttribute(string.Format("This is a synthetic *property* created by me for {0}.{1}", this._DeclaringType.Namespace, this._DeclaringType.Name))));
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderDefinitionLocationAttribute() { Column = 21, FilePath = "File.fs", Line = 3 }));
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderEditorHideMethodsAttribute()));
+            return attrs;
+        }
+
+    }
+}
diff --git a/vsintegration/src/unittests/Resources.MockTypeProviders/DefinitionLocationAttribute/ArtificialType.cs b/vsintegration/src/unittests/Resources.MockTypeProviders/DefinitionLocationAttribute/ArtificialType.cs
new file mode 100644
index 0000000..c1e379d
--- /dev/null
+++ b/vsintegration/src/unittests/Resources.MockTypeProviders/DefinitionLocationAttribute/ArtificialType.cs
@@ -0,0 +1,744 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Reflection;
+using Microsoft.FSharp.Core.CompilerServices;
+
+namespace TypeProviderInCSharp
+{
+    public class ArtificialType : Type
+    {
+        string _Namespace;
+        string _Name;
+        bool _IsGenericType;
+        bool _IsValueType;  // value type = not class / not interface
+        bool _IsByRef;      // is the value passed by reference?
+        bool _IsEnum;
+        bool _IsPointer;
+
+        Type _BaseType;
+        MethodInfo _Method1;
+        PropertyInfo _Property1;
+        EventInfo _Event1;
+        FieldInfo _Field1;
+        ConstructorInfo _Ctor1;
+
+        public ArtificialType(string @namespace, string name, bool isGenericType, Type basetype, bool isValueType, bool isByRef, bool isEnum, bool IsPointer)
+        {
+            _Name = name;
+            _Namespace = @namespace;
+            _IsGenericType = isGenericType;
+            _BaseType = basetype;
+            _IsValueType = isValueType;
+            _IsByRef = isByRef;
+            _IsEnum = isEnum;
+            _IsPointer = IsPointer;
+            _Method1 = new ArtificialMethodInfo("M", this, typeof(int[]), MethodAttributes.Public | MethodAttributes.Static);
+            _Property1 = new ArtificialPropertyInfo("StaticProp", this, typeof(decimal), true, false);
+            _Event1 = new ArtificalEventInfo("Event1", this, typeof(EventHandler));
+            _Ctor1 = new ArtificialConstructorInfo(this, new ParameterInfo[] {} );  // parameter-less ctor
+        }
+
+        public override System.Reflection.Assembly Assembly
+        {
+            get 
+            { 
+                return Assembly.GetExecutingAssembly();
+            }
+        }
+
+        public override string Name
+        {
+            get 
+            { 
+                return _Name;
+            }
+        }
+
+        public override Type BaseType
+        {
+            get
+            {
+                return _BaseType;
+            }
+        }
+
+        public override string Namespace
+        {
+            get
+            {
+                return _Namespace;
+            }
+        }
+
+        public override string FullName
+        {
+            get
+            { 
+                return string.Format("{0}.{1}", _Namespace, _Name);
+            }
+        }
+
+        public override object[] GetCustomAttributes(Type attributeType, bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        public override object[] GetCustomAttributes(bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        // TODO: what is this?
+        protected override System.Reflection.TypeAttributes GetAttributeFlagsImpl()
+        {
+            return TypeAttributes.Class | TypeAttributes.Public | (TypeAttributes)0x40000000; // add the special flag to indicate an erased type, see TypeProviderTypeAttributes  
+        }
+
+        // This one seems to be invoked when in IDE, I type something like:
+        // let _ = typeof<N.
+        // In this case => no constructors
+        public override System.Reflection.ConstructorInfo[] GetConstructors(System.Reflection.BindingFlags bindingAttr)
+        {
+            // According to the spec, we should only expect these 4, so we guard against that here!
+            Debug.Assert(bindingAttr == (BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly), "bindingAttr has value not according to the spec!");
+            if (_Ctor1!=null) 
+                return new System.Reflection.ConstructorInfo[] { _Ctor1 };
+            else
+                return new System.Reflection.ConstructorInfo[] { };
+        }
+
+        // When you start typing more interesting things like...
+        // let a = N.T.M()
+        // this one gets invoked...
+        public override System.Reflection.MethodInfo[] GetMethods(System.Reflection.BindingFlags bindingAttr)
+        {
+            // According to the spec, we should only expect these 4, so we guard against that here!
+            Debug.Assert(bindingAttr == (BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly), "bindingAttr has value not according to the spec!");
+            return new[] { _Method1 };
+        }
+
+        // This method is called when in the source file we have something like:
+        // - N.T.StaticProp 
+        // (most likely also when we have an instance prop...)
+        // name -> "StaticProp"
+        protected override System.Reflection.PropertyInfo GetPropertyImpl(string name, System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder binder, Type returnType, Type[] types, System.Reflection.ParameterModifier[] modifiers)
+        {
+            // According to the spec, we should only expect these 4, so we guard against that here!
+            Debug.Assert(bindingAttr == (BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly), "bindingAttr has value not according to the spec!");
+            Debug.Assert(binder == null && returnType == null && types == null && modifiers == null, "One of binder, returnType, types, or modifiers was not null");
+            if (name == _Property1.Name)
+                return _Property1;
+            else
+                return null;
+        }
+
+        // Advertise our property...
+        // I think that is this one returns an empty array => you don't get intellisense/autocomplete in IDE/FSI
+        public override System.Reflection.PropertyInfo[] GetProperties(System.Reflection.BindingFlags bindingAttr)
+        {
+            // According to the spec, we should only expect these 4, so we guard against that here!
+            Debug.Assert(bindingAttr == (BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly), "bindingAttr has value not according to the spec!");
+            return new PropertyInfo[] { _Property1 };
+        }
+
+        // No fields...
+        public override System.Reflection.FieldInfo GetField(string name, System.Reflection.BindingFlags bindingAttr)
+        {
+            // According to the spec, we should only expect these 4, so we guard against that here!
+            Debug.Assert(bindingAttr == (BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly), "bindingAttr has value not according to the spec!");
+            return null;
+        }
+
+        public override System.Reflection.FieldInfo[] GetFields(System.Reflection.BindingFlags bindingAttr)
+        {
+            // According to the spec, we should only expect these 4, so we guard against that here!
+            Debug.Assert(bindingAttr == (BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly), "bindingAttr has value not according to the spec!");
+            return new System.Reflection.FieldInfo[] { };
+        }
+
+        // Events
+        public override System.Reflection.EventInfo GetEvent(string name, System.Reflection.BindingFlags bindingAttr)
+        {
+            // According to the spec, we should only expect these 4, so we guard against that here!
+            Debug.Assert(bindingAttr == (BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly), "bindingAttr has value not according to the spec!");
+            if (_Event1 != null && _Event1.Name == name)
+                return _Event1;
+            else
+                return null;
+        }
+
+        // Events...
+        public override System.Reflection.EventInfo[] GetEvents(System.Reflection.BindingFlags bindingAttr)
+        {
+            return _Event1 != null ? new [] { _Event1 } : new System.Reflection.EventInfo[] { };
+        }
+
+        // TODO: according to the spec, this should not be invoked... instead it seems like it may be invoked...
+        //       ?? I have no idea what this is used for... ??
+        public override Type UnderlyingSystemType
+        {
+            get
+            {
+                return null;
+            }
+        }
+
+        // According to the spec, this should always be 'false'
+        protected override bool IsArrayImpl()
+        {
+            return false;    
+        }
+
+        // No interfaces...
+        public override Type[] GetInterfaces()
+        {
+            return new Type[] { };
+        }
+
+        // No nested type
+        // This method is invoked on the type 'T', e.g.:
+        //    let _ = N.T.M
+        // to figure out if M is a nested type.
+        public override Type GetNestedType(string name, System.Reflection.BindingFlags bindingAttr)
+        {
+            return null;
+        }
+        public override Type[] GetNestedTypes(System.Reflection.BindingFlags bindingAttr)
+        {
+            // According to the spec, we should only expect these 4, so we guard against that here!
+            Debug.Assert(bindingAttr == (BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly), "bindingAttr has value not according to the spec!");
+            return new Type[] { };
+        }
+
+        // This one is invoked when the type has a .ctor 
+        // and the code looks like
+        // let _ = new N.T()
+        // for example.
+        // It was observed that the
+        // TODO: cover both cases!
+        public override bool IsGenericType
+        {
+            get
+            {
+                return _IsGenericType;
+            }
+        }
+
+        // This is invoked if the IsGenericType is true
+        public override Type[] GetGenericArguments()
+        {
+            if (_IsGenericType)
+                return new Type[] { typeof(int), typeof(decimal), typeof(System.Guid) };        // This is currently triggering an ICE...
+            else
+            {
+                Debug.Assert(false, "Why are we here?");
+                throw new NotImplementedException();
+            }
+
+        }
+
+        // This one seems to be invoked when compiling something like
+        // let a = new N.T()
+        // Let's just stay away from generics...
+        public override bool IsGenericTypeDefinition
+        {
+            get
+            {
+                return _IsGenericType;
+            }
+        }
+
+        // This one seems to be invoked when compiling something like
+        // let a = new N.T()
+        // Let's just stay away from generics...
+        public override bool ContainsGenericParameters
+        {
+            get
+            {
+                return _IsGenericType;
+            }
+        }
+
+        // This one seems to be checked when in IDE.
+        // let b = N.T(
+        protected override bool IsValueTypeImpl()
+        {
+            return _IsValueType;
+        }
+
+        // This one seems to be checked when in IDE.
+        // let b = N.T(
+        protected override bool IsByRefImpl()
+        {
+            return _IsByRef;
+        }
+
+        // This one seems to be checked when in IDE.
+        // let b = N.T(
+        public override bool IsEnum
+        {
+            get
+            {
+                
+                return _IsEnum;
+            }
+        }
+
+        // This one seems to be checked when in IDE.
+        // let b = N.T(
+        protected override bool IsPointerImpl()
+        {
+            
+            return _IsPointer;
+        }
+
+        public override string AssemblyQualifiedName
+        {
+            get 
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override Guid GUID
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        protected override System.Reflection.ConstructorInfo GetConstructorImpl(System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder binder, System.Reflection.CallingConventions callConvention, Type[] types, System.Reflection.ParameterModifier[] modifiers)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override Type GetElementType()
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override Type GetInterface(string name, bool ignoreCase)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override System.Reflection.MemberInfo[] GetMembers(System.Reflection.BindingFlags bindingAttr)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        protected override System.Reflection.MethodInfo GetMethodImpl(string name, System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder binder, System.Reflection.CallingConventions callConvention, Type[] types, System.Reflection.ParameterModifier[] modifiers)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        protected override bool HasElementTypeImpl()
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override object InvokeMember(string name, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, object target, object[] args, System.Reflection.ParameterModifier[] modifiers, System.Globalization.CultureInfo culture, string[] namedParameters)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        protected override bool IsCOMObjectImpl()
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        protected override bool IsPrimitiveImpl()
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override System.Reflection.Module Module
+        {
+            get {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override bool IsDefined(Type attributeType, bool inherit)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override MethodBase DeclaringMethod
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.DeclaringMethod;
+            }
+        }
+
+        // This one is invoked by the F# compiler!
+        public override Type DeclaringType
+        {
+            get
+            {
+                
+                return null; // base.DeclaringType;
+            }
+        }
+
+        public override Type[] FindInterfaces(TypeFilter filter, object filterCriteria)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.FindInterfaces(filter, filterCriteria);
+        }
+
+        public override MemberInfo[] FindMembers(MemberTypes memberType, BindingFlags bindingAttr, MemberFilter filter, object filterCriteria)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.FindMembers(memberType, bindingAttr, filter, filterCriteria);
+        }
+
+        public override GenericParameterAttributes GenericParameterAttributes
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.GenericParameterAttributes;
+            }
+        }
+
+        public override int GenericParameterPosition
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.GenericParameterPosition;
+            }
+        }
+
+        public override int GetArrayRank()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetArrayRank();
+        }
+
+        public override MemberInfo[] GetDefaultMembers()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetDefaultMembers();
+        }
+
+        public override string GetEnumName(object value)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetEnumName(value);
+        }
+
+        public override string[] GetEnumNames()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetEnumNames();
+        }
+
+        public override Type GetEnumUnderlyingType()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetEnumUnderlyingType();
+        }
+
+        public override Array GetEnumValues()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetEnumValues();
+        }
+
+        public override EventInfo[] GetEvents()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetEvents();
+        }
+
+        public override Type[] GetGenericParameterConstraints()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetGenericParameterConstraints();
+        }
+
+        public override Type GetGenericTypeDefinition()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetGenericTypeDefinition();
+        }
+
+        public override InterfaceMapping GetInterfaceMap(Type interfaceType)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetInterfaceMap(interfaceType);
+        }
+
+        public override MemberInfo[] GetMember(string name, BindingFlags bindingAttr)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetMember(name, bindingAttr);
+        }
+
+        public override MemberInfo[] GetMember(string name, MemberTypes type, BindingFlags bindingAttr)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetMember(name, type, bindingAttr);
+        }
+
+        protected override TypeCode GetTypeCodeImpl()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetTypeCodeImpl();
+        }
+
+        public override bool IsAssignableFrom(Type c)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.IsAssignableFrom(c);
+        }
+
+        protected override bool IsContextfulImpl()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.IsContextfulImpl();
+        }
+
+        public override bool IsEnumDefined(object value)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.IsEnumDefined(value);
+        }
+
+        public override bool IsEquivalentTo(Type other)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.IsEquivalentTo(other);
+        }
+
+        public override bool IsGenericParameter
+        {
+            get
+            {
+                return _IsGenericType;
+            }
+        }
+
+        public override bool IsInstanceOfType(object o)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.IsInstanceOfType(o);
+        }
+
+        protected override bool IsMarshalByRefImpl()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.IsMarshalByRefImpl();
+        }
+
+        public override bool IsSecurityCritical
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.IsSecurityCritical;
+            }
+        }
+
+        public override bool IsSecuritySafeCritical
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.IsSecuritySafeCritical;
+            }
+        }
+
+        public override bool IsSecurityTransparent
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.IsSecurityTransparent;
+            }
+        }
+
+        public override bool IsSerializable
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.IsSerializable;
+            }
+        }
+
+        public override bool IsSubclassOf(Type c)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.IsSubclassOf(c);
+        }
+
+        public override Type MakeArrayType()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.MakeArrayType();
+        }
+
+        public override Type MakeArrayType(int rank)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.MakeArrayType(rank);
+        }
+
+        public override Type MakeByRefType()
+        {
+            return base.MakeByRefType();
+        }
+
+        public override Type MakeGenericType(params Type[] typeArguments)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.MakeGenericType(typeArguments);
+        }
+
+        public override Type MakePointerType()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.MakePointerType();
+        }
+
+        public override MemberTypes MemberType
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.MemberType;
+            }
+        }
+
+        public override int MetadataToken
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.MetadataToken;
+            }
+        }
+
+        public override Type ReflectedType
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.ReflectedType;
+            }
+        }
+
+        public override System.Runtime.InteropServices.StructLayoutAttribute StructLayoutAttribute
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.StructLayoutAttribute;
+            }
+        }
+
+        public override RuntimeTypeHandle TypeHandle
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.TypeHandle;
+            }
+        }
+
+        public override string ToString()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.ToString();
+        }
+
+        public override IList<CustomAttributeData> GetCustomAttributesData()
+        {
+            var attrs = new List<CustomAttributeData>();
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderXmlDocAttribute("This is a synthetic type created by me!")));
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderDefinitionLocationAttribute() { Column = 21, FilePath = "File.fs", Line = 3 }));
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderEditorHideMethodsAttribute()));
+            return attrs;
+        }
+
+    }
+
+}
diff --git a/vsintegration/src/unittests/Resources.MockTypeProviders/DefinitionLocationAttribute/DefinitionLocationAttribute.csproj b/vsintegration/src/unittests/Resources.MockTypeProviders/DefinitionLocationAttribute/DefinitionLocationAttribute.csproj
new file mode 100644
index 0000000..d242a5c
--- /dev/null
+++ b/vsintegration/src/unittests/Resources.MockTypeProviders/DefinitionLocationAttribute/DefinitionLocationAttribute.csproj
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information. -->
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <FSharpSourcesRoot>..\..\..\..\..\src</FSharpSourcesRoot>
+    <ProjectLanguage>CSharp</ProjectLanguage>
+  </PropertyGroup>  
+  <Import Project="$(FSharpSourcesRoot)\FSharpSource.settings.targets" />
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{DA39AD38-4A58-47BF-9215-E49768295169}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AssemblyName>DefinitionLocationAttribute</AssemblyName>
+    <DefineConstants>DEBUG;TRACE;$(DefineConstants)</DefineConstants>
+    <WarningLevel>4</WarningLevel>
+    <NoWarn>0169;0067</NoWarn>
+    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+    <OutputPath>$(FSharpSourcesRoot)\..\$(Configuration)\$(TargetFramework)\bin\UnitTestsResources\MockTypeProviders</OutputPath>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+    <ProjectReference Include="$(FSharpSourcesRoot)\fsharp\FSharp.Core\FSharp.Core.fsproj">
+      <Project>{DED3BBD7-53F4-428A-8C9F-27968E768605}</Project>
+      <Name>FSharp.Core</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="ArtificalEventInfo.cs" />
+    <Compile Include="ArtificialConstructorInfo.cs" />
+    <Compile Include="ArtificialMethodInfo.cs" />
+    <Compile Include="ArtificialParamInfo.cs" />
+    <Compile Include="ArtificialType.cs" />
+    <Compile Include="ArtificialPropertyInfo.cs" />
+    <Compile Include="TypeProviderInCSharp.cs" />
+    <Compile Include="..\Helpers.cs" />
+  </ItemGroup>
+
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+
+</Project>
\ No newline at end of file
diff --git a/vsintegration/src/unittests/Resources.MockTypeProviders/DefinitionLocationAttribute/TypeProviderInCSharp.cs b/vsintegration/src/unittests/Resources.MockTypeProviders/DefinitionLocationAttribute/TypeProviderInCSharp.cs
new file mode 100644
index 0000000..240a998
--- /dev/null
+++ b/vsintegration/src/unittests/Resources.MockTypeProviders/DefinitionLocationAttribute/TypeProviderInCSharp.cs
@@ -0,0 +1,150 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Microsoft.FSharp.Core.CompilerServices;
+using Microsoft.FSharp.Quotations;
+using System.Reflection;
+using System.Diagnostics;
+
+[assembly: TypeProviderAssembly()]
+
+namespace TypeProviderInCSharp
+{
+    //namespace N
+    //{
+    //    class S
+    //    {
+    //        public int instanceField;
+    //        public S(int x)
+    //        {
+    //            instanceField = x;
+    //        }
+    //    }
+    //}
+
+    class Namespace1 : IProvidedNamespace
+    {
+        const string _Namespace = "N";
+        const string _Name = "T";
+
+        // Type myType = new myType(typeof(N.S), "Bad.Name", typeof(Action), true);
+        Type myType = new ArtificialType(_Namespace, _Name, false, basetype: typeof(object), isValueType: false, isByRef: false, isEnum: false, IsPointer: false);
+
+        public IProvidedNamespace[] GetNestedNamespaces()
+        {
+
+            return new IProvidedNamespace[] { };
+        }
+
+        public Type[] GetTypes()
+        {
+
+            return new Type[] { myType };
+        }
+
+        public string NamespaceName
+        {
+            get { return _Namespace; }
+        }
+
+        public Type ResolveTypeName(string typeName)
+        {
+
+            if (typeName == _Name)
+            {
+                return myType;
+            }
+            return null;
+        }
+    }
+
+    [TypeProvider()]
+    public class TypeProvider : ITypeProvider
+    {
+        void IDisposable.Dispose()
+        {
+        }
+        private void Param(int staticParam)
+        {
+        }
+
+        public Type ApplyStaticArguments(Type typeWithoutArguments, string[] typeNameWithArguments, object[] staticArguments)
+        {
+            //Console.WriteLine("Hello from ApplyStaticArguments");
+            //var n = new myType(typeof(N.S), "S,\"1\"", typeof(object), false);
+            //return n;
+
+            return null;
+        }
+
+        public FSharpExpr GetInvokerExpression(System.Reflection.MethodBase syntheticMethodBase, FSharpExpr[] parameters)
+        {
+
+            if (syntheticMethodBase is System.Reflection.ConstructorInfo)
+            {
+                var ac = syntheticMethodBase as ArtificialConstructorInfo;
+                if (ac.DeclaringType.FullName == "N.T")
+                {
+                    return FSharpExpr.DefaultValue(ac.DeclaringType.BaseType);
+                }
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+            else if (syntheticMethodBase is System.Reflection.MethodInfo)
+            {
+                var am = syntheticMethodBase as ArtificialMethodInfo;
+                if (am.DeclaringType.FullName == "N.T" && am.Name == "M")
+                {
+                    return FSharpExpr.Lambda(FSharpVar.Global("", typeof(int[])), FSharpExpr.Value<int[]>(new[] { 1, 2, 3 }));
+                }
+                else if (am.DeclaringType.FullName == "N.T" && am.Name == "get_StaticProp")
+                {
+                    return FSharpExpr.Lambda(FSharpVar.Global("", typeof(decimal)), FSharpExpr.Value<decimal>(4.2M));
+                }
+                else if (am.DeclaringType.FullName == "N.T" && am.Name == "add_Event1")
+                {
+                    // Dummy expr... since we do not care about what it really does...
+                    return FSharpExpr.Lambda(FSharpVar.Global("", typeof(int)), FSharpExpr.Value<int>(1));
+                }
+                else if (am.DeclaringType.FullName == "N.T" && am.Name == "remove_Event1")
+                {
+                    // Dummy expr... since we do not care about what it really does...
+                    return FSharpExpr.Lambda(FSharpVar.Global("", typeof(int)), FSharpExpr.Value<int>(1));
+                }
+                else
+                {
+                    Debug.Assert(false, "NYI");
+                    throw new NotImplementedException();
+                }
+            }
+            else
+            {
+                Debug.Assert(false, "GetInvokerExpression() invoked with neither ConstructorInfo nor MethodInfo!");
+                return null;
+            }
+            //Expression<Func<S>> e = () => new S(9);
+            //return e.Body;
+
+            //throw new NotImplementedException();
+        }
+
+        public IProvidedNamespace[] GetNamespaces()
+        {
+
+            return new IProvidedNamespace[] { new Namespace1() };
+        }
+
+        public System.Reflection.ParameterInfo[] GetStaticParameters(Type typeWithoutArguments)
+        {
+
+            // No StaticParams
+            return new ParameterInfo[] { /* new myParameterInfo() */ };
+        }
+        public byte[] GetGeneratedAssemblyContents(Assembly assembly) { throw (new Exception("GetGeneratedAssemblyContents - only erased types were provided!!")); }
+
+        public event EventHandler Invalidate;
+    }
+}
diff --git a/vsintegration/src/unittests/Resources.MockTypeProviders/DefinitionLocationAttributeFileDoesnotExist/ArtificalEventInfo.cs b/vsintegration/src/unittests/Resources.MockTypeProviders/DefinitionLocationAttributeFileDoesnotExist/ArtificalEventInfo.cs
new file mode 100644
index 0000000..4e10a3e
--- /dev/null
+++ b/vsintegration/src/unittests/Resources.MockTypeProviders/DefinitionLocationAttributeFileDoesnotExist/ArtificalEventInfo.cs
@@ -0,0 +1,130 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Reflection;
+using Microsoft.FSharp.Core.CompilerServices;
+
+namespace TypeProviderInCSharp
+{
+    class ArtificalEventInfo : EventInfo
+    {
+        string _Name;
+        Type _DeclaringType;
+        Type _EventHandleType;
+        MethodInfo _AddMethod;
+        MethodInfo _RemoveMethod;
+
+        public ArtificalEventInfo(string Name, Type DeclaringType, Type EventHandleType)
+        {
+            _Name = Name;
+            _DeclaringType = DeclaringType;
+            _EventHandleType = EventHandleType;
+
+            _AddMethod = new ArtificialMethodInfo("add_" + _Name, _DeclaringType, typeof(void), MethodAttributes.FamANDAssem | MethodAttributes.Family | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.Public);
+            _RemoveMethod = new ArtificialMethodInfo("remove_" + _Name, _DeclaringType, typeof(void), MethodAttributes.FamANDAssem | MethodAttributes.Family | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.Public);
+        }
+
+        // This one is invoked
+        public override Type EventHandlerType
+        {
+            get
+            {
+                
+                return _EventHandleType;
+            }
+        }
+
+        public override string Name
+        {
+            get 
+            { 
+                
+                return _Name;
+            }
+        }
+
+        public override Type DeclaringType
+        {
+            get
+            {
+                
+                return _DeclaringType;
+            }
+        }
+
+        // This one is needed
+        public override MethodInfo GetAddMethod(bool nonPublic)
+        {
+            
+            Debug.Assert(!nonPublic, "GetAddMethod() was called with nonPublic=true");
+            return _AddMethod;
+        }
+
+        // This one is needed
+        public override MethodInfo GetRemoveMethod(bool nonPublic)
+        {
+            
+            Debug.Assert(!nonPublic, "GetRemoveMethod() was called with nonPublic=true");
+            return _RemoveMethod;
+        }
+
+        public override object[] GetCustomAttributes(Type attributeType, bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        public override EventAttributes Attributes
+        {
+            get
+            {
+                
+                return EventAttributes.None;
+            }
+        }
+
+        public override MethodInfo GetRaiseMethod(bool nonPublic)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override object[] GetCustomAttributes(bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        public override bool IsDefined(Type attributeType, bool inherit)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override Type ReflectedType
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override IList<CustomAttributeData> GetCustomAttributesData()
+        {
+            var attrs = new List<CustomAttributeData>();
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderXmlDocAttribute(string.Format("This is a synthetic *event* created by me for {0}.{1}", this._DeclaringType.Namespace, this._DeclaringType.Name))));
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderDefinitionLocationAttribute() { Column = 21, FilePath = "Temp.fs", Line = 4 }));
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderEditorHideMethodsAttribute()));
+            return attrs;
+        }
+
+    }
+}
diff --git a/vsintegration/src/unittests/Resources.MockTypeProviders/DefinitionLocationAttributeFileDoesnotExist/ArtificialConstructorInfo.cs b/vsintegration/src/unittests/Resources.MockTypeProviders/DefinitionLocationAttributeFileDoesnotExist/ArtificialConstructorInfo.cs
new file mode 100644
index 0000000..0b7f5ea
--- /dev/null
+++ b/vsintegration/src/unittests/Resources.MockTypeProviders/DefinitionLocationAttributeFileDoesnotExist/ArtificialConstructorInfo.cs
@@ -0,0 +1,135 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Reflection;
+using Microsoft.FSharp.Core.CompilerServices;
+
+namespace TypeProviderInCSharp
+{
+    class ArtificialConstructorInfo : ConstructorInfo
+    {
+        Type _DeclaringType;
+        ParameterInfo[] _ParameterInfo;
+
+        public ArtificialConstructorInfo(Type DeclaringType, ParameterInfo[] ParamInfo)
+        {
+            _DeclaringType = DeclaringType;
+            _ParameterInfo = ParamInfo;
+        }
+
+        public override Type DeclaringType
+        {
+            get
+            {
+                
+                return _DeclaringType;
+            }
+        }
+
+        // This one is invoked
+        public override ParameterInfo[] GetParameters()
+        {
+            
+            return _ParameterInfo;
+        }
+
+        // This one is indeed invoked
+        // I believe we should always return ".ctor"
+        public override string Name
+        {
+            get
+            {
+                
+                return ".ctor";
+            }
+        }
+
+        // Does it matter what we return here?
+        // This property is definitely checked by the compiler in code like this:
+        // let _ = new N.T()
+        // I copied the attribute set from the .ctor of System.DateTime - the documentation on MSDN assumes that one is already familiar with
+        // what they mean (=totally useless, as often happens)
+        public override MethodAttributes Attributes
+        {
+            get
+            {
+                
+                return MethodAttributes.FamANDAssem | MethodAttributes.Family | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName;
+            }
+        }
+
+        public override object[] GetCustomAttributes(Type attributeType, bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        public override object Invoke(BindingFlags invokeAttr, Binder binder, object[] parameters, System.Globalization.CultureInfo culture)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override MethodImplAttributes GetMethodImplementationFlags()
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override object Invoke(object obj, BindingFlags invokeAttr, Binder binder, object[] parameters, System.Globalization.CultureInfo culture)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override RuntimeMethodHandle MethodHandle
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override object[] GetCustomAttributes(bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        public override bool IsDefined(Type attributeType, bool inherit)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override Type ReflectedType
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override IList<CustomAttributeData> GetCustomAttributesData()
+        {
+            var attrs = new List<CustomAttributeData>();
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderXmlDocAttribute(string.Format("This is a synthetic .ctor created by me for {0}.{1}", this._DeclaringType.Namespace, this._DeclaringType.Name))));
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderDefinitionLocationAttribute() { Column = 21, FilePath = "Temp.fs", Line = 3 }));
+            // attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderEditorHideMethodsAttribute()));
+            return attrs;
+        }
+
+    }
+}
diff --git a/vsintegration/src/unittests/Resources.MockTypeProviders/DefinitionLocationAttributeFileDoesnotExist/ArtificialMethodInfo.cs b/vsintegration/src/unittests/Resources.MockTypeProviders/DefinitionLocationAttributeFileDoesnotExist/ArtificialMethodInfo.cs
new file mode 100644
index 0000000..d63c3e3
--- /dev/null
+++ b/vsintegration/src/unittests/Resources.MockTypeProviders/DefinitionLocationAttributeFileDoesnotExist/ArtificialMethodInfo.cs
@@ -0,0 +1,168 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Reflection;
+using Microsoft.FSharp.Core.CompilerServices;
+
+namespace TypeProviderInCSharp
+{
+    class ArtificialMethodInfo : MethodInfo
+    {
+        string _Name;
+        Type _DeclaringType;
+        Type _ReturnType;
+        MethodAttributes _MethodAttributes;
+
+        public ArtificialMethodInfo(string Name, Type DeclaringType, Type ReturnType, MethodAttributes MethodAttributes)
+        {
+            _Name = Name;
+            _DeclaringType = DeclaringType;
+            _ReturnType = ReturnType;
+            _MethodAttributes = MethodAttributes;
+        }
+
+        public override string Name
+        {
+            get 
+            { 
+                
+                return _Name;
+            }
+        }
+
+        public override Type DeclaringType
+        {
+            get
+            {
+                
+                return _DeclaringType;
+            }
+        }
+
+        // Make the method Public and Static - 
+        // TODO: should be configurable in the ctor...
+        public override MethodAttributes Attributes
+        {
+            get
+            {
+                
+                return _MethodAttributes;
+            }
+        }
+
+        // No params
+        // TODO: should be configurable in the ctor...
+        public override ParameterInfo[] GetParameters()
+        {
+            
+            return new ParameterInfo[] {  };
+        }
+
+        public override ParameterInfo ReturnParameter
+        {
+            get
+            {
+                //
+                //var retvalpi = new ArtificialParamInfo(typeof(List<>), true);
+                //return retvalpi;
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+
+            }
+        }
+
+        public override Type ReturnType
+        {
+            get
+            {
+                
+                return _ReturnType;
+            }
+        }
+
+        public override MethodInfo GetBaseDefinition()
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override ICustomAttributeProvider ReturnTypeCustomAttributes
+        {
+            get 
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override MethodImplAttributes GetMethodImplementationFlags()
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override object Invoke(object obj, BindingFlags invokeAttr, Binder binder, object[] parameters, System.Globalization.CultureInfo culture)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override RuntimeMethodHandle MethodHandle
+        {
+            get 
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override object[] GetCustomAttributes(Type attributeType, bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        public override object[] GetCustomAttributes(bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        public override bool IsDefined(Type attributeType, bool inherit)
+        {
+            
+            Debug.Assert(false, "NYI"); 
+            throw new NotImplementedException();
+        }
+
+        public override Type ReflectedType
+        {
+            get 
+            { 
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override IList<CustomAttributeData> GetCustomAttributesData()
+        {
+            var attrs = new List<CustomAttributeData>();
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderXmlDocAttribute("This is a synthetic *method* created by me!!")));
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderDefinitionLocationAttribute() { Column = 5, FilePath = "Temp.fs", Line = 3 }));
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderEditorHideMethodsAttribute()));
+            return attrs;
+        }
+
+    }
+}
diff --git a/vsintegration/src/unittests/Resources.MockTypeProviders/DefinitionLocationAttributeFileDoesnotExist/ArtificialParamInfo.cs b/vsintegration/src/unittests/Resources.MockTypeProviders/DefinitionLocationAttributeFileDoesnotExist/ArtificialParamInfo.cs
new file mode 100644
index 0000000..6624f2d
--- /dev/null
+++ b/vsintegration/src/unittests/Resources.MockTypeProviders/DefinitionLocationAttributeFileDoesnotExist/ArtificialParamInfo.cs
@@ -0,0 +1,156 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Reflection;
+using Microsoft.FSharp.Core.CompilerServices;
+
+namespace TypeProviderInCSharp
+{
+    public class ArtificialParamInfo : ParameterInfo
+    {
+        Type _type;
+        bool _isRetVal;
+
+        public ArtificialParamInfo(Type type, bool isRetVal)
+        {
+            _type = type;
+            _isRetVal = IsRetval;
+        }
+
+        // TODO: allow more customizations...
+        public override ParameterAttributes Attributes
+        {
+            get
+            {
+                return _isRetVal ? ParameterAttributes.Retval : ParameterAttributes.None;
+            }
+        }
+
+        public override Type ParameterType
+        {
+            get
+            {
+                return _type;
+            }
+        }
+
+        public override object DefaultValue
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override bool Equals(object obj)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override object[] GetCustomAttributes(bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        public override object[] GetCustomAttributes(Type attributeType, bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        public override int GetHashCode()
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override Type[] GetOptionalCustomModifiers()
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override Type[] GetRequiredCustomModifiers()
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override bool IsDefined(Type attributeType, bool inherit)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override MemberInfo Member
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override int MetadataToken
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override string Name
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override int Position
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override object RawDefaultValue
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override string ToString()
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+    }
+
+}
diff --git a/vsintegration/src/unittests/Resources.MockTypeProviders/DefinitionLocationAttributeFileDoesnotExist/ArtificialPropertyInfo.cs b/vsintegration/src/unittests/Resources.MockTypeProviders/DefinitionLocationAttributeFileDoesnotExist/ArtificialPropertyInfo.cs
new file mode 100644
index 0000000..d19b6ca
--- /dev/null
+++ b/vsintegration/src/unittests/Resources.MockTypeProviders/DefinitionLocationAttributeFileDoesnotExist/ArtificialPropertyInfo.cs
@@ -0,0 +1,180 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Reflection;
+using Microsoft.FSharp.Core.CompilerServices;
+
+namespace TypeProviderInCSharp
+{
+    class ArtificialPropertyInfo : PropertyInfo
+    {
+        string _Name;
+        bool _CanRead;
+        bool _CanWrite;
+        Type _DeclaringType;
+        Type _PropertyType;
+
+        MethodInfo _GetMethod;
+        MethodInfo _SetMethod;
+
+        public ArtificialPropertyInfo(string Name, Type DeclaringType, Type PropertyType, bool CanRead, bool CanWrite)
+        {
+            _Name = Name;
+            _DeclaringType = DeclaringType;
+            _PropertyType = PropertyType;
+            _CanRead = CanRead;
+            _CanWrite = CanWrite;
+
+            if(CanRead)
+                _GetMethod = new ArtificialMethodInfo("get_" + _Name, _DeclaringType, _PropertyType, MethodAttributes.Public | MethodAttributes.Static);
+            if (CanWrite)
+                _SetMethod = new ArtificialMethodInfo("set_" + _Name, _DeclaringType, null /* ?? */, MethodAttributes.Public | MethodAttributes.Static);
+
+        }
+
+        // The name of this property...
+        public override string Name
+        {
+            get
+            {
+                
+                return _Name;
+            }
+        }
+
+        // Needed
+        public override bool CanRead
+        {
+            get
+            {
+                
+                return _CanRead;
+            }
+        }
+
+        // If CanRead is true, this one gets invoked.
+        public override MethodInfo GetGetMethod(bool nonPublic)
+        {
+            
+            Debug.Assert(!nonPublic, "GetGetMethod was invoked with nonPublic=true");
+            return _GetMethod;
+        }
+
+        // Why is this invoked?
+        public override ParameterInfo[] GetIndexParameters()
+        {
+            
+            return new ParameterInfo[] { /* new ArtificialParamInfo(typeof(int), isRetVal: false), new ArtificialParamInfo(typeof(decimal), isRetVal: false) */};
+        }
+
+        // If CanRead is false, this one gets invoked... without checking 'CanWrite' (?)
+        public override MethodInfo GetSetMethod(bool nonPublic)
+        {
+            
+            return _SetMethod;
+        }
+
+        public override bool CanWrite
+        {
+            get
+            {
+                
+                return _CanWrite;
+            }
+        }
+
+        // Interestingly enough, this one seems to be invoked only when I hover over the property in the IDE...
+        public override Type PropertyType
+        {
+            get
+            {
+                
+                return _PropertyType;
+            }
+        }
+
+        // Interestingly enough, this one seems to be invoked only when I hover over the property in the IDE...
+        public override Type DeclaringType
+        {
+            get
+            {
+                
+                return _DeclaringType;
+            }
+        }
+
+        public override object[] GetCustomAttributes(Type attributeType, bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+
+        public override PropertyAttributes Attributes
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override MethodInfo[] GetAccessors(bool nonPublic)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override object GetValue(object obj, BindingFlags invokeAttr, Binder binder, object[] index, System.Globalization.CultureInfo culture)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override void SetValue(object obj, object value, BindingFlags invokeAttr, Binder binder, object[] index, System.Globalization.CultureInfo culture)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override object[] GetCustomAttributes(bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        public override bool IsDefined(Type attributeType, bool inherit)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override Type ReflectedType
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override IList<CustomAttributeData> GetCustomAttributesData()
+        {
+            var attrs = new List<CustomAttributeData>();
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderXmlDocAttribute(string.Format("This is a synthetic *property* created by me for {0}.{1}", this._DeclaringType.Namespace, this._DeclaringType.Name))));
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderDefinitionLocationAttribute() { Column = 21, FilePath = "Temp.fs", Line = 3 }));
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderEditorHideMethodsAttribute()));
+            return attrs;
+        }
+    }
+}
diff --git a/vsintegration/src/unittests/Resources.MockTypeProviders/DefinitionLocationAttributeFileDoesnotExist/ArtificialType.cs b/vsintegration/src/unittests/Resources.MockTypeProviders/DefinitionLocationAttributeFileDoesnotExist/ArtificialType.cs
new file mode 100644
index 0000000..18febfe
--- /dev/null
+++ b/vsintegration/src/unittests/Resources.MockTypeProviders/DefinitionLocationAttributeFileDoesnotExist/ArtificialType.cs
@@ -0,0 +1,769 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Reflection;
+using Microsoft.FSharp.Core.CompilerServices;
+
+namespace TypeProviderInCSharp
+{
+    public class ArtificialType : Type
+    {
+        string _Namespace;
+        string _Name;
+        bool _IsGenericType;
+        bool _IsValueType;  // value type = not class / not interface
+        bool _IsByRef;      // is the value passed by reference?
+        bool _IsEnum;
+        bool _IsPointer;
+
+        Type _BaseType;
+        MethodInfo _Method1;
+        PropertyInfo _Property1;
+        EventInfo _Event1;
+        FieldInfo _Field1;
+        ConstructorInfo _Ctor1;
+
+        public ArtificialType(string @namespace, string name, bool isGenericType, Type basetype, bool isValueType, bool isByRef, bool isEnum, bool IsPointer)
+        {
+            _Name = name;
+            _Namespace = @namespace;
+            _IsGenericType = isGenericType;
+            _BaseType = basetype;
+            _IsValueType = isValueType;
+            _IsByRef = isByRef;
+            _IsEnum = isEnum;
+            _IsPointer = IsPointer;
+            _Method1 = new ArtificialMethodInfo("M", this, typeof(int[]), MethodAttributes.Public | MethodAttributes.Static);
+            _Property1 = new ArtificialPropertyInfo("StaticProp", this, typeof(decimal), true, false);
+            _Event1 = new ArtificalEventInfo("Event1", this, typeof(EventHandler));
+            _Ctor1 = new ArtificialConstructorInfo(this, new ParameterInfo[] {} );  // parameter-less ctor
+        }
+
+        public override System.Reflection.Assembly Assembly
+        {
+            get 
+            { 
+                
+                return Assembly.GetExecutingAssembly();
+            }
+        }
+
+        public override string Name
+        {
+            get 
+            { 
+                
+                return _Name;
+            }
+        }
+
+        public override Type BaseType
+        {
+            get
+            {
+                
+                return _BaseType;
+            }
+        }
+
+        public override string Namespace
+        {
+            get
+            {
+                
+                return _Namespace;
+            }
+        }
+
+        public override string FullName
+        {
+            get
+            { 
+                
+                return string.Format("{0}.{1}", _Namespace, _Name);
+            }
+        }
+
+        public override object[] GetCustomAttributes(Type attributeType, bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        public override object[] GetCustomAttributes(bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        // TODO: what is this?
+        protected override System.Reflection.TypeAttributes GetAttributeFlagsImpl()
+        {
+
+            return TypeAttributes.Class | TypeAttributes.Public | (TypeAttributes)0x40000000; // add the special flag to indicate an erased type, see TypeProviderTypeAttributes
+        }
+
+        // This one seems to be invoked when in IDE, I type something like:
+        // let _ = typeof<N.
+        // In this case => no constructors
+        public override System.Reflection.ConstructorInfo[] GetConstructors(System.Reflection.BindingFlags bindingAttr)
+        {
+            
+            // According to the spec, we should only expect these 4, so we guard against that here!
+            Debug.Assert(bindingAttr == (BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly), "bindingAttr has value not according to the spec!");
+            if (_Ctor1!=null) 
+                return new System.Reflection.ConstructorInfo[] { _Ctor1 };
+            else
+                return new System.Reflection.ConstructorInfo[] { };
+        }
+
+        // When you start typing more interesting things like...
+        // let a = N.T.M()
+        // this one gets invoked...
+        public override System.Reflection.MethodInfo[] GetMethods(System.Reflection.BindingFlags bindingAttr)
+        {
+            
+            // According to the spec, we should only expect these 4, so we guard against that here!
+            Debug.Assert(bindingAttr == (BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly), "bindingAttr has value not according to the spec!");
+            return new[] { _Method1 };
+        }
+
+        // This method is called when in the source file we have something like:
+        // - N.T.StaticProp 
+        // (most likely also when we have an instance prop...)
+        // name -> "StaticProp"
+        protected override System.Reflection.PropertyInfo GetPropertyImpl(string name, System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder binder, Type returnType, Type[] types, System.Reflection.ParameterModifier[] modifiers)
+        {
+            
+            // According to the spec, we should only expect these 4, so we guard against that here!
+            Debug.Assert(bindingAttr == (BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly), "bindingAttr has value not according to the spec!");
+            Debug.Assert(binder == null && returnType == null && types == null && modifiers == null, "One of binder, returnType, types, or modifiers was not null");
+            if (name == _Property1.Name)
+                return _Property1;
+            else
+                return null;
+        }
+
+        // Advertise our property...
+        // I think that is this one returns an empty array => you don't get intellisense/autocomplete in IDE/FSI
+        public override System.Reflection.PropertyInfo[] GetProperties(System.Reflection.BindingFlags bindingAttr)
+        {
+            
+            // According to the spec, we should only expect these 4, so we guard against that here!
+            Debug.Assert(bindingAttr == (BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly), "bindingAttr has value not according to the spec!");
+            return new PropertyInfo[] { _Property1 };
+        }
+
+        // No fields...
+        public override System.Reflection.FieldInfo GetField(string name, System.Reflection.BindingFlags bindingAttr)
+        {
+            
+            // According to the spec, we should only expect these 4, so we guard against that here!
+            Debug.Assert(bindingAttr == (BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly), "bindingAttr has value not according to the spec!");
+            return null;
+        }
+
+        public override System.Reflection.FieldInfo[] GetFields(System.Reflection.BindingFlags bindingAttr)
+        {
+            
+            // According to the spec, we should only expect these 4, so we guard against that here!
+            Debug.Assert(bindingAttr == (BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly), "bindingAttr has value not according to the spec!");
+            return new System.Reflection.FieldInfo[] { };
+        }
+
+        // Events
+        public override System.Reflection.EventInfo GetEvent(string name, System.Reflection.BindingFlags bindingAttr)
+        {
+            
+            // According to the spec, we should only expect these 4, so we guard against that here!
+            Debug.Assert(bindingAttr == (BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly), "bindingAttr has value not according to the spec!");
+            if (_Event1 != null && _Event1.Name == name)
+                return _Event1;
+            else
+                return null;
+        }
+
+        // Events...
+        public override System.Reflection.EventInfo[] GetEvents(System.Reflection.BindingFlags bindingAttr)
+        {
+            
+            return _Event1 != null ? new [] { _Event1 } : new System.Reflection.EventInfo[] { };
+        }
+
+        // TODO: according to the spec, this should not be invoked... instead it seems like it may be invoked...
+        //       ?? I have no idea what this is used for... ??
+        public override Type UnderlyingSystemType
+        {
+            get
+            {
+                
+                return null;
+            }
+        }
+
+        // According to the spec, this should always be 'false'
+        protected override bool IsArrayImpl()
+        {
+            
+            return false;    
+        }
+
+        // No interfaces...
+        public override Type[] GetInterfaces()
+        {
+            
+            return new Type[] { };
+        }
+
+        // No nested type
+        // This method is invoked on the type 'T', e.g.:
+        //    let _ = N.T.M
+        // to figure out if M is a nested type.
+        public override Type GetNestedType(string name, System.Reflection.BindingFlags bindingAttr)
+        {
+            
+            return null;
+        }
+        public override Type[] GetNestedTypes(System.Reflection.BindingFlags bindingAttr)
+        {
+            
+            // According to the spec, we should only expect these 4, so we guard against that here!
+            Debug.Assert(bindingAttr == (BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly), "bindingAttr has value not according to the spec!");
+            return new Type[] { };
+        }
+
+        // This one is invoked when the type has a .ctor 
+        // and the code looks like
+        // let _ = new N.T()
+        // for example.
+        // It was observed that the
+        // TODO: cover both cases!
+        public override bool IsGenericType
+        {
+            get
+            {
+                
+                return _IsGenericType;
+            }
+        }
+
+        // This is invoked if the IsGenericType is true
+        public override Type[] GetGenericArguments()
+        {
+            
+            if (_IsGenericType)
+                return new Type[] { typeof(int), typeof(decimal), typeof(System.Guid) };        // This is currently triggering an ICE...
+            else
+            {
+                Debug.Assert(false, "Why are we here?");
+                throw new NotImplementedException();
+            }
+
+        }
+
+        // This one seems to be invoked when compiling something like
+        // let a = new N.T()
+        // Let's just stay away from generics...
+        public override bool IsGenericTypeDefinition
+        {
+            get
+            {
+                
+                return _IsGenericType;
+            }
+        }
+
+        // This one seems to be invoked when compiling something like
+        // let a = new N.T()
+        // Let's just stay away from generics...
+        public override bool ContainsGenericParameters
+        {
+            get
+            {
+                
+                return _IsGenericType;
+            }
+        }
+
+        // This one seems to be checked when in IDE.
+        // let b = N.T(
+        protected override bool IsValueTypeImpl()
+        {
+            
+            return _IsValueType;
+        }
+
+        // This one seems to be checked when in IDE.
+        // let b = N.T(
+        protected override bool IsByRefImpl()
+        {
+            
+            return _IsByRef;
+        }
+
+        // This one seems to be checked when in IDE.
+        // let b = N.T(
+        public override bool IsEnum
+        {
+            get
+            {
+                
+                return _IsEnum;
+            }
+        }
+
+        // This one seems to be checked when in IDE.
+        // let b = N.T(
+        protected override bool IsPointerImpl()
+        {
+            
+            return _IsPointer;
+        }
+
+        public override string AssemblyQualifiedName
+        {
+            get 
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override Guid GUID
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        protected override System.Reflection.ConstructorInfo GetConstructorImpl(System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder binder, System.Reflection.CallingConventions callConvention, Type[] types, System.Reflection.ParameterModifier[] modifiers)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override Type GetElementType()
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override Type GetInterface(string name, bool ignoreCase)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override System.Reflection.MemberInfo[] GetMembers(System.Reflection.BindingFlags bindingAttr)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        protected override System.Reflection.MethodInfo GetMethodImpl(string name, System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder binder, System.Reflection.CallingConventions callConvention, Type[] types, System.Reflection.ParameterModifier[] modifiers)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        protected override bool HasElementTypeImpl()
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override object InvokeMember(string name, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, object target, object[] args, System.Reflection.ParameterModifier[] modifiers, System.Globalization.CultureInfo culture, string[] namedParameters)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        protected override bool IsCOMObjectImpl()
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        protected override bool IsPrimitiveImpl()
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override System.Reflection.Module Module
+        {
+            get {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override bool IsDefined(Type attributeType, bool inherit)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override MethodBase DeclaringMethod
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.DeclaringMethod;
+            }
+        }
+
+        // This one is invoked by the F# compiler!
+        public override Type DeclaringType
+        {
+            get
+            {
+                
+                return null; // base.DeclaringType;
+            }
+        }
+
+        public override Type[] FindInterfaces(TypeFilter filter, object filterCriteria)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.FindInterfaces(filter, filterCriteria);
+        }
+
+        public override MemberInfo[] FindMembers(MemberTypes memberType, BindingFlags bindingAttr, MemberFilter filter, object filterCriteria)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.FindMembers(memberType, bindingAttr, filter, filterCriteria);
+        }
+
+        public override GenericParameterAttributes GenericParameterAttributes
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.GenericParameterAttributes;
+            }
+        }
+
+        public override int GenericParameterPosition
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.GenericParameterPosition;
+            }
+        }
+
+        public override int GetArrayRank()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetArrayRank();
+        }
+
+        public override MemberInfo[] GetDefaultMembers()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetDefaultMembers();
+        }
+
+        public override string GetEnumName(object value)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetEnumName(value);
+        }
+
+        public override string[] GetEnumNames()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetEnumNames();
+        }
+
+        public override Type GetEnumUnderlyingType()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetEnumUnderlyingType();
+        }
+
+        public override Array GetEnumValues()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetEnumValues();
+        }
+
+        public override EventInfo[] GetEvents()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetEvents();
+        }
+
+        public override Type[] GetGenericParameterConstraints()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetGenericParameterConstraints();
+        }
+
+        public override Type GetGenericTypeDefinition()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetGenericTypeDefinition();
+        }
+
+        public override InterfaceMapping GetInterfaceMap(Type interfaceType)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetInterfaceMap(interfaceType);
+        }
+
+        public override MemberInfo[] GetMember(string name, BindingFlags bindingAttr)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetMember(name, bindingAttr);
+        }
+
+        public override MemberInfo[] GetMember(string name, MemberTypes type, BindingFlags bindingAttr)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetMember(name, type, bindingAttr);
+        }
+
+        protected override TypeCode GetTypeCodeImpl()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetTypeCodeImpl();
+        }
+
+        public override bool IsAssignableFrom(Type c)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.IsAssignableFrom(c);
+        }
+
+        protected override bool IsContextfulImpl()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.IsContextfulImpl();
+        }
+
+        public override bool IsEnumDefined(object value)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.IsEnumDefined(value);
+        }
+
+        public override bool IsEquivalentTo(Type other)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.IsEquivalentTo(other);
+        }
+
+        public override bool IsGenericParameter
+        {
+            get
+            {
+                return _IsGenericType;
+            }
+        }
+
+        public override bool IsInstanceOfType(object o)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.IsInstanceOfType(o);
+        }
+
+        protected override bool IsMarshalByRefImpl()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.IsMarshalByRefImpl();
+        }
+
+        public override bool IsSecurityCritical
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.IsSecurityCritical;
+            }
+        }
+
+        public override bool IsSecuritySafeCritical
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.IsSecuritySafeCritical;
+            }
+        }
+
+        public override bool IsSecurityTransparent
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.IsSecurityTransparent;
+            }
+        }
+
+        public override bool IsSerializable
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.IsSerializable;
+            }
+        }
+
+        public override bool IsSubclassOf(Type c)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.IsSubclassOf(c);
+        }
+
+        public override Type MakeArrayType()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.MakeArrayType();
+        }
+
+        public override Type MakeArrayType(int rank)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.MakeArrayType(rank);
+        }
+
+        public override Type MakeByRefType()
+        {
+            return base.MakeByRefType();
+        }
+
+        public override Type MakeGenericType(params Type[] typeArguments)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.MakeGenericType(typeArguments);
+        }
+
+        public override Type MakePointerType()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.MakePointerType();
+        }
+
+        public override MemberTypes MemberType
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.MemberType;
+            }
+        }
+
+        public override int MetadataToken
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.MetadataToken;
+            }
+        }
+
+        public override Type ReflectedType
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.ReflectedType;
+            }
+        }
+
+        public override System.Runtime.InteropServices.StructLayoutAttribute StructLayoutAttribute
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.StructLayoutAttribute;
+            }
+        }
+
+        public override RuntimeTypeHandle TypeHandle
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.TypeHandle;
+            }
+        }
+
+        public override string ToString()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.ToString();
+        }
+
+        public override IList<CustomAttributeData> GetCustomAttributesData()
+        {
+            var attrs = new List<CustomAttributeData>();
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderXmlDocAttribute("This is a synthetic type created by me!")));
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderDefinitionLocationAttribute() { Column = 21, FilePath = "Temp.fs", Line = 3 }));
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderEditorHideMethodsAttribute()));
+            return attrs;
+        }
+
+    }
+
+}
diff --git a/vsintegration/src/unittests/Resources.MockTypeProviders/DefinitionLocationAttributeFileDoesnotExist/DefinitionLocationAttributeFileDoesnotExist.csproj b/vsintegration/src/unittests/Resources.MockTypeProviders/DefinitionLocationAttributeFileDoesnotExist/DefinitionLocationAttributeFileDoesnotExist.csproj
new file mode 100644
index 0000000..41c552a
--- /dev/null
+++ b/vsintegration/src/unittests/Resources.MockTypeProviders/DefinitionLocationAttributeFileDoesnotExist/DefinitionLocationAttributeFileDoesnotExist.csproj
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information. -->
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <FSharpSourcesRoot>..\..\..\..\..\src</FSharpSourcesRoot>
+    <ProjectLanguage>CSharp</ProjectLanguage>
+  </PropertyGroup>  
+  <Import Project="$(FSharpSourcesRoot)\FSharpSource.settings.targets" />
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{8C2439BD-0E49-4929-A8B1-29CEE228191E}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AssemblyName>DefinitionLocationAttributeFileDoesnotExist</AssemblyName>
+    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+    <DefineConstants>DEBUG;TRACE;$(DefineConstants)</DefineConstants>
+    <WarningLevel>4</WarningLevel>
+    <NoWarn>0169;0067</NoWarn>
+    <OutputPath>$(FSharpSourcesRoot)\..\$(Configuration)\$(TargetFramework)\bin\UnitTestsResources\MockTypeProviders</OutputPath>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+    <ProjectReference Include="$(FSharpSourcesRoot)\fsharp\FSharp.Core\FSharp.Core.fsproj">
+      <Project>{DED3BBD7-53F4-428A-8C9F-27968E768605}</Project>
+      <Name>FSharp.Core</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="ArtificalEventInfo.cs" />
+    <Compile Include="ArtificialConstructorInfo.cs" />
+    <Compile Include="ArtificialMethodInfo.cs" />
+    <Compile Include="ArtificialParamInfo.cs" />
+    <Compile Include="ArtificialType.cs" />
+    <Compile Include="ArtificialPropertyInfo.cs" />
+    <Compile Include="TypeProviderInCSharp.cs" />
+    <Compile Include="..\Helpers.cs" />
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+</Project>
\ No newline at end of file
diff --git a/vsintegration/src/unittests/Resources.MockTypeProviders/DefinitionLocationAttributeFileDoesnotExist/TypeProviderInCSharp.cs b/vsintegration/src/unittests/Resources.MockTypeProviders/DefinitionLocationAttributeFileDoesnotExist/TypeProviderInCSharp.cs
new file mode 100644
index 0000000..e4c569b
--- /dev/null
+++ b/vsintegration/src/unittests/Resources.MockTypeProviders/DefinitionLocationAttributeFileDoesnotExist/TypeProviderInCSharp.cs
@@ -0,0 +1,150 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Microsoft.FSharp.Core.CompilerServices;
+using Microsoft.FSharp.Quotations;
+using System.Reflection;
+using System.Diagnostics;
+
+[assembly: TypeProviderAssembly()]
+
+namespace TypeProviderInCSharp
+{
+    //namespace N
+    //{
+    //    class S
+    //    {
+    //        public int instanceField;
+    //        public S(int x)
+    //        {
+    //            instanceField = x;
+    //        }
+    //    }
+    //}
+
+    class Namespace1 : IProvidedNamespace
+    {
+        const string _Namespace = "N";
+        const string _Name = "T";
+
+        // Type myType = new myType(typeof(N.S), "Bad.Name", typeof(Action), true);
+        Type myType = new ArtificialType(_Namespace, _Name, false, basetype: typeof(object), isValueType: false, isByRef: false, isEnum: false, IsPointer: false);
+
+        public IProvidedNamespace[] GetNestedNamespaces()
+        {
+
+            return new IProvidedNamespace[] { };
+        }
+
+        public Type[] GetTypes()
+        {
+
+            return new Type[] { myType };
+        }
+
+        public string NamespaceName
+        {
+            get { return _Namespace; }
+        }
+
+        public Type ResolveTypeName(string typeName)
+        {
+
+            if (typeName == _Name)
+            {
+                return myType;
+            }
+            return null;
+        }
+    }
+
+    [TypeProvider()]
+    public class TypeProvider : ITypeProvider
+    {
+        void IDisposable.Dispose()
+        {
+        }
+        private void Param(int staticParam)
+        {
+        }
+
+        public Type ApplyStaticArguments(Type typeWithoutArguments, string[] typeNameWithArguments, object[] staticArguments)
+        {
+            //Console.WriteLine("Hello from ApplyStaticArguments");
+            //var n = new myType(typeof(N.S), "S,\"1\"", typeof(object), false);
+            //return n;
+
+            return null;
+        }
+
+        public FSharpExpr GetInvokerExpression(System.Reflection.MethodBase syntheticMethodBase, FSharpExpr[] parameters)
+        {
+
+            if (syntheticMethodBase is System.Reflection.ConstructorInfo)
+            {
+                var ac = syntheticMethodBase as ArtificialConstructorInfo;
+                if (ac.DeclaringType.FullName == "N.T")
+                {
+                    return FSharpExpr.DefaultValue(ac.DeclaringType.BaseType);
+                }
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+            else if (syntheticMethodBase is System.Reflection.MethodInfo)
+            {
+                var am = syntheticMethodBase as ArtificialMethodInfo;
+                if (am.DeclaringType.FullName == "N.T" && am.Name == "M")
+                {
+                    return FSharpExpr.Lambda(FSharpVar.Global("", typeof(int[])), FSharpExpr.Value<int[]>(new[] { 1, 2, 3 }));
+                }
+                else if (am.DeclaringType.FullName == "N.T" && am.Name == "get_StaticProp")
+                {
+                    return FSharpExpr.Lambda(FSharpVar.Global("", typeof(decimal)), FSharpExpr.Value<decimal>(4.2M));
+                }
+                else if (am.DeclaringType.FullName == "N.T" && am.Name == "add_Event1")
+                {
+                    // Dummy expr... since we do not care about what it really does...
+                    return FSharpExpr.Lambda(FSharpVar.Global("", typeof(int)), FSharpExpr.Value<int>(1));
+                }
+                else if (am.DeclaringType.FullName == "N.T" && am.Name == "remove_Event1")
+                {
+                    // Dummy expr... since we do not care about what it really does...
+                    return FSharpExpr.Lambda(FSharpVar.Global("", typeof(int)), FSharpExpr.Value<int>(1));
+                }
+                else
+                {
+                    Debug.Assert(false, "NYI");
+                    throw new NotImplementedException();
+                }
+            }
+            else
+            {
+                Debug.Assert(false, "GetInvokerExpression() invoked with neither ConstructorInfo nor MethodInfo!");
+                return null;
+            }
+            //Expression<Func<S>> e = () => new S(9);
+            //return e.Body;
+
+            //throw new NotImplementedException();
+        }
+
+        public IProvidedNamespace[] GetNamespaces()
+        {
+
+            return new IProvidedNamespace[] { new Namespace1() };
+        }
+
+        public System.Reflection.ParameterInfo[] GetStaticParameters(Type typeWithoutArguments)
+        {
+
+            // No StaticParams
+            return new ParameterInfo[] { /* new myParameterInfo() */ };
+        }
+
+        public event EventHandler Invalidate;
+        public byte[] GetGeneratedAssemblyContents(Assembly assembly) { throw (new Exception("GetGeneratedAssemblyContents - only erased types were provided!!")); }
+    }
+}
diff --git a/vsintegration/src/unittests/Resources.MockTypeProviders/DefinitionLocationAttributeLineDoesnotExist/ArtificalEventInfo.cs b/vsintegration/src/unittests/Resources.MockTypeProviders/DefinitionLocationAttributeLineDoesnotExist/ArtificalEventInfo.cs
new file mode 100644
index 0000000..edf9c2c
--- /dev/null
+++ b/vsintegration/src/unittests/Resources.MockTypeProviders/DefinitionLocationAttributeLineDoesnotExist/ArtificalEventInfo.cs
@@ -0,0 +1,129 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Reflection;
+using Microsoft.FSharp.Core.CompilerServices;
+
+namespace TypeProviderInCSharp
+{
+    class ArtificalEventInfo : EventInfo
+    {
+        string _Name;
+        Type _DeclaringType;
+        Type _EventHandleType;
+        MethodInfo _AddMethod;
+        MethodInfo _RemoveMethod;
+
+        public ArtificalEventInfo(string Name, Type DeclaringType, Type EventHandleType)
+        {
+            _Name = Name;
+            _DeclaringType = DeclaringType;
+            _EventHandleType = EventHandleType;
+
+            _AddMethod = new ArtificialMethodInfo("add_" + _Name, _DeclaringType, typeof(void), MethodAttributes.FamANDAssem | MethodAttributes.Family | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.Public);
+            _RemoveMethod = new ArtificialMethodInfo("remove_" + _Name, _DeclaringType, typeof(void), MethodAttributes.FamANDAssem | MethodAttributes.Family | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.Public);
+        }
+
+        // This one is invoked
+        public override Type EventHandlerType
+        {
+            get
+            {
+                
+                return _EventHandleType;
+            }
+        }
+
+        public override string Name
+        {
+            get 
+            { 
+                
+                return _Name;
+            }
+        }
+
+        public override Type DeclaringType
+        {
+            get
+            {
+                
+                return _DeclaringType;
+            }
+        }
+
+        // This one is needed
+        public override MethodInfo GetAddMethod(bool nonPublic)
+        {
+            
+            Debug.Assert(!nonPublic, "GetAddMethod() was called with nonPublic=true");
+            return _AddMethod;
+        }
+
+        // This one is needed
+        public override MethodInfo GetRemoveMethod(bool nonPublic)
+        {
+            
+            Debug.Assert(!nonPublic, "GetRemoveMethod() was called with nonPublic=true");
+            return _RemoveMethod;
+        }
+
+        public override object[] GetCustomAttributes(Type attributeType, bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        public override EventAttributes Attributes
+        {
+            get
+            {
+                
+                return EventAttributes.None;
+            }
+        }
+
+        public override MethodInfo GetRaiseMethod(bool nonPublic)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override object[] GetCustomAttributes(bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        public override bool IsDefined(Type attributeType, bool inherit)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override Type ReflectedType
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override IList<CustomAttributeData> GetCustomAttributesData()
+        {
+            var attrs = new List<CustomAttributeData>();
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderXmlDocAttribute(string.Format("This is a synthetic *event* created by me for {0}.{1}", this._DeclaringType.Namespace, this._DeclaringType.Name))));
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderDefinitionLocationAttribute() { Column = 21, FilePath = "File.fs", Line = 50 }));
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderEditorHideMethodsAttribute()));
+            return attrs;
+        }
+    }
+}
diff --git a/vsintegration/src/unittests/Resources.MockTypeProviders/DefinitionLocationAttributeLineDoesnotExist/ArtificialConstructorInfo.cs b/vsintegration/src/unittests/Resources.MockTypeProviders/DefinitionLocationAttributeLineDoesnotExist/ArtificialConstructorInfo.cs
new file mode 100644
index 0000000..2fd2c42
--- /dev/null
+++ b/vsintegration/src/unittests/Resources.MockTypeProviders/DefinitionLocationAttributeLineDoesnotExist/ArtificialConstructorInfo.cs
@@ -0,0 +1,135 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Reflection;
+using Microsoft.FSharp.Core.CompilerServices;
+
+namespace TypeProviderInCSharp
+{
+    class ArtificialConstructorInfo : ConstructorInfo
+    {
+        Type _DeclaringType;
+        ParameterInfo[] _ParameterInfo;
+
+        public ArtificialConstructorInfo(Type DeclaringType, ParameterInfo[] ParamInfo)
+        {
+            _DeclaringType = DeclaringType;
+            _ParameterInfo = ParamInfo;
+        }
+
+        public override Type DeclaringType
+        {
+            get
+            {
+                
+                return _DeclaringType;
+            }
+        }
+
+        // This one is invoked
+        public override ParameterInfo[] GetParameters()
+        {
+            
+            return _ParameterInfo;
+        }
+
+        // This one is indeed invoked
+        // I believe we should always return ".ctor"
+        public override string Name
+        {
+            get
+            {
+                
+                return ".ctor";
+            }
+        }
+
+        // Does it matter what we return here?
+        // This property is definitely checked by the compiler in code like this:
+        // let _ = new N.T()
+        // I copied the attribute set from the .ctor of System.DateTime - the documentation on MSDN assumes that one is already familiar with
+        // what they mean (=totally useless, as often happens)
+        public override MethodAttributes Attributes
+        {
+            get
+            {
+                
+                return MethodAttributes.FamANDAssem | MethodAttributes.Family | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName;
+            }
+        }
+
+        public override object[] GetCustomAttributes(Type attributeType, bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        public override object Invoke(BindingFlags invokeAttr, Binder binder, object[] parameters, System.Globalization.CultureInfo culture)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override MethodImplAttributes GetMethodImplementationFlags()
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override object Invoke(object obj, BindingFlags invokeAttr, Binder binder, object[] parameters, System.Globalization.CultureInfo culture)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override RuntimeMethodHandle MethodHandle
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override object[] GetCustomAttributes(bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        public override bool IsDefined(Type attributeType, bool inherit)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override Type ReflectedType
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override IList<CustomAttributeData> GetCustomAttributesData()
+        {
+            var attrs = new List<CustomAttributeData>();
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderXmlDocAttribute(string.Format("This is a synthetic .ctor created by me for {0}.{1}", this._DeclaringType.Namespace, this._DeclaringType.Name))));
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderDefinitionLocationAttribute() { Column = 21, FilePath = "File.fs", Line = 50 }));
+            // attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderEditorHideMethodsAttribute()));
+            return attrs;
+        }
+
+    }
+}
diff --git a/vsintegration/src/unittests/Resources.MockTypeProviders/DefinitionLocationAttributeLineDoesnotExist/ArtificialMethodInfo.cs b/vsintegration/src/unittests/Resources.MockTypeProviders/DefinitionLocationAttributeLineDoesnotExist/ArtificialMethodInfo.cs
new file mode 100644
index 0000000..686f1f4
--- /dev/null
+++ b/vsintegration/src/unittests/Resources.MockTypeProviders/DefinitionLocationAttributeLineDoesnotExist/ArtificialMethodInfo.cs
@@ -0,0 +1,168 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Reflection;
+using Microsoft.FSharp.Core.CompilerServices;
+
+namespace TypeProviderInCSharp
+{
+    class ArtificialMethodInfo : MethodInfo
+    {
+        string _Name;
+        Type _DeclaringType;
+        Type _ReturnType;
+        MethodAttributes _MethodAttributes;
+
+        public ArtificialMethodInfo(string Name, Type DeclaringType, Type ReturnType, MethodAttributes MethodAttributes)
+        {
+            _Name = Name;
+            _DeclaringType = DeclaringType;
+            _ReturnType = ReturnType;
+            _MethodAttributes = MethodAttributes;
+        }
+
+        public override string Name
+        {
+            get 
+            { 
+                
+                return _Name;
+            }
+        }
+
+        public override Type DeclaringType
+        {
+            get
+            {
+                
+                return _DeclaringType;
+            }
+        }
+
+        // Make the method Public and Static - 
+        // TODO: should be configurable in the ctor...
+        public override MethodAttributes Attributes
+        {
+            get
+            {
+                
+                return _MethodAttributes;
+            }
+        }
+
+        // No params
+        // TODO: should be configurable in the ctor...
+        public override ParameterInfo[] GetParameters()
+        {
+            
+            return new ParameterInfo[] {  };
+        }
+
+        public override ParameterInfo ReturnParameter
+        {
+            get
+            {
+                //
+                //var retvalpi = new ArtificialParamInfo(typeof(List<>), true);
+                //return retvalpi;
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+
+            }
+        }
+
+        public override Type ReturnType
+        {
+            get
+            {
+                
+                return _ReturnType;
+            }
+        }
+
+        public override MethodInfo GetBaseDefinition()
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override ICustomAttributeProvider ReturnTypeCustomAttributes
+        {
+            get 
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override MethodImplAttributes GetMethodImplementationFlags()
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override object Invoke(object obj, BindingFlags invokeAttr, Binder binder, object[] parameters, System.Globalization.CultureInfo culture)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override RuntimeMethodHandle MethodHandle
+        {
+            get 
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override object[] GetCustomAttributes(Type attributeType, bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        public override object[] GetCustomAttributes(bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        public override bool IsDefined(Type attributeType, bool inherit)
+        {
+            
+            Debug.Assert(false, "NYI"); 
+            throw new NotImplementedException();
+        }
+
+        public override Type ReflectedType
+        {
+            get 
+            { 
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override IList<CustomAttributeData> GetCustomAttributesData()
+        {
+            var attrs = new List<CustomAttributeData>();
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderXmlDocAttribute("This is a synthetic *method* created by me!!")));
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderDefinitionLocationAttribute() { Column = 21, FilePath = "File.fs", Line = 50 }));
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderEditorHideMethodsAttribute()));
+            return attrs;
+        }
+
+    }
+}
diff --git a/vsintegration/src/unittests/Resources.MockTypeProviders/DefinitionLocationAttributeLineDoesnotExist/ArtificialParamInfo.cs b/vsintegration/src/unittests/Resources.MockTypeProviders/DefinitionLocationAttributeLineDoesnotExist/ArtificialParamInfo.cs
new file mode 100644
index 0000000..6624f2d
--- /dev/null
+++ b/vsintegration/src/unittests/Resources.MockTypeProviders/DefinitionLocationAttributeLineDoesnotExist/ArtificialParamInfo.cs
@@ -0,0 +1,156 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Reflection;
+using Microsoft.FSharp.Core.CompilerServices;
+
+namespace TypeProviderInCSharp
+{
+    public class ArtificialParamInfo : ParameterInfo
+    {
+        Type _type;
+        bool _isRetVal;
+
+        public ArtificialParamInfo(Type type, bool isRetVal)
+        {
+            _type = type;
+            _isRetVal = IsRetval;
+        }
+
+        // TODO: allow more customizations...
+        public override ParameterAttributes Attributes
+        {
+            get
+            {
+                return _isRetVal ? ParameterAttributes.Retval : ParameterAttributes.None;
+            }
+        }
+
+        public override Type ParameterType
+        {
+            get
+            {
+                return _type;
+            }
+        }
+
+        public override object DefaultValue
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override bool Equals(object obj)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override object[] GetCustomAttributes(bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        public override object[] GetCustomAttributes(Type attributeType, bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        public override int GetHashCode()
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override Type[] GetOptionalCustomModifiers()
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override Type[] GetRequiredCustomModifiers()
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override bool IsDefined(Type attributeType, bool inherit)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override MemberInfo Member
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override int MetadataToken
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override string Name
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override int Position
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override object RawDefaultValue
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override string ToString()
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+    }
+
+}
diff --git a/vsintegration/src/unittests/Resources.MockTypeProviders/DefinitionLocationAttributeLineDoesnotExist/ArtificialPropertyInfo.cs b/vsintegration/src/unittests/Resources.MockTypeProviders/DefinitionLocationAttributeLineDoesnotExist/ArtificialPropertyInfo.cs
new file mode 100644
index 0000000..8547cb9
--- /dev/null
+++ b/vsintegration/src/unittests/Resources.MockTypeProviders/DefinitionLocationAttributeLineDoesnotExist/ArtificialPropertyInfo.cs
@@ -0,0 +1,181 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Reflection;
+using Microsoft.FSharp.Core.CompilerServices;
+
+namespace TypeProviderInCSharp
+{
+    class ArtificialPropertyInfo : PropertyInfo
+    {
+        string _Name;
+        bool _CanRead;
+        bool _CanWrite;
+        Type _DeclaringType;
+        Type _PropertyType;
+
+        MethodInfo _GetMethod;
+        MethodInfo _SetMethod;
+
+        public ArtificialPropertyInfo(string Name, Type DeclaringType, Type PropertyType, bool CanRead, bool CanWrite)
+        {
+            _Name = Name;
+            _DeclaringType = DeclaringType;
+            _PropertyType = PropertyType;
+            _CanRead = CanRead;
+            _CanWrite = CanWrite;
+
+            if(CanRead)
+                _GetMethod = new ArtificialMethodInfo("get_" + _Name, _DeclaringType, _PropertyType, MethodAttributes.Public | MethodAttributes.Static);
+            if (CanWrite)
+                _SetMethod = new ArtificialMethodInfo("set_" + _Name, _DeclaringType, null /* ?? */, MethodAttributes.Public | MethodAttributes.Static);
+
+        }
+
+        // The name of this property...
+        public override string Name
+        {
+            get
+            {
+                
+                return _Name;
+            }
+        }
+
+        // Needed
+        public override bool CanRead
+        {
+            get
+            {
+                
+                return _CanRead;
+            }
+        }
+
+        // If CanRead is true, this one gets invoked.
+        public override MethodInfo GetGetMethod(bool nonPublic)
+        {
+            
+            Debug.Assert(!nonPublic, "GetGetMethod was invoked with nonPublic=true");
+            return _GetMethod;
+        }
+
+        // Why is this invoked?
+        public override ParameterInfo[] GetIndexParameters()
+        {
+            
+            return new ParameterInfo[] { /* new ArtificialParamInfo(typeof(int), isRetVal: false), new ArtificialParamInfo(typeof(decimal), isRetVal: false) */};
+        }
+
+        // If CanRead is false, this one gets invoked... without checking 'CanWrite' (?)
+        public override MethodInfo GetSetMethod(bool nonPublic)
+        {
+            
+            return _SetMethod;
+        }
+
+        public override bool CanWrite
+        {
+            get
+            {
+                
+                return _CanWrite;
+            }
+        }
+
+        // Interestingly enough, this one seems to be invoked only when I hover over the property in the IDE...
+        public override Type PropertyType
+        {
+            get
+            {
+                
+                return _PropertyType;
+            }
+        }
+
+        // Interestingly enough, this one seems to be invoked only when I hover over the property in the IDE...
+        public override Type DeclaringType
+        {
+            get
+            {
+                
+                return _DeclaringType;
+            }
+        }
+
+        public override object[] GetCustomAttributes(Type attributeType, bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+
+        public override PropertyAttributes Attributes
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override MethodInfo[] GetAccessors(bool nonPublic)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override object GetValue(object obj, BindingFlags invokeAttr, Binder binder, object[] index, System.Globalization.CultureInfo culture)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override void SetValue(object obj, object value, BindingFlags invokeAttr, Binder binder, object[] index, System.Globalization.CultureInfo culture)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override object[] GetCustomAttributes(bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        public override bool IsDefined(Type attributeType, bool inherit)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override Type ReflectedType
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override IList<CustomAttributeData> GetCustomAttributesData()
+        {
+            var attrs = new List<CustomAttributeData>();
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderXmlDocAttribute(string.Format("This is a synthetic *property* created by me for {0}.{1}", this._DeclaringType.Namespace, this._DeclaringType.Name))));
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderDefinitionLocationAttribute() { Column = 21, FilePath = "File.fs", Line = 50 }));
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderEditorHideMethodsAttribute()));
+            return attrs;
+        }
+
+    }
+}
diff --git a/vsintegration/src/unittests/Resources.MockTypeProviders/DefinitionLocationAttributeLineDoesnotExist/ArtificialType.cs b/vsintegration/src/unittests/Resources.MockTypeProviders/DefinitionLocationAttributeLineDoesnotExist/ArtificialType.cs
new file mode 100644
index 0000000..0f16675
--- /dev/null
+++ b/vsintegration/src/unittests/Resources.MockTypeProviders/DefinitionLocationAttributeLineDoesnotExist/ArtificialType.cs
@@ -0,0 +1,771 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Reflection;
+using Microsoft.FSharp.Core.CompilerServices;
+
+namespace TypeProviderInCSharp
+{
+    public class ArtificialType : Type
+    {
+        string _Namespace;
+        string _Name;
+        bool _IsGenericType;
+        bool _IsValueType;  // value type = not class / not interface
+        bool _IsByRef;      // is the value passed by reference?
+        bool _IsEnum;
+        bool _IsPointer;
+
+        Type _BaseType;
+        MethodInfo _Method1;
+        PropertyInfo _Property1;
+        EventInfo _Event1;
+        FieldInfo _Field1;
+        ConstructorInfo _Ctor1;
+
+        public ArtificialType(string @namespace, string name, bool isGenericType, Type basetype, bool isValueType, bool isByRef, bool isEnum, bool IsPointer)
+        {
+            _Name = name;
+            _Namespace = @namespace;
+            _IsGenericType = isGenericType;
+            _BaseType = basetype;
+            _IsValueType = isValueType;
+            _IsByRef = isByRef;
+            _IsEnum = isEnum;
+            _IsPointer = IsPointer;
+            _Method1 = new ArtificialMethodInfo("M", this, typeof(int[]), MethodAttributes.Public | MethodAttributes.Static);
+            _Property1 = new ArtificialPropertyInfo("StaticProp", this, typeof(decimal), true, false);
+            _Event1 = new ArtificalEventInfo("Event1", this, typeof(EventHandler));
+            _Ctor1 = new ArtificialConstructorInfo(this, new ParameterInfo[] {} );  // parameter-less ctor
+        }
+
+        public override System.Reflection.Assembly Assembly
+        {
+            get 
+            { 
+                
+                return Assembly.GetExecutingAssembly();
+            }
+        }
+
+        public override string Name
+        {
+            get 
+            { 
+                
+                return _Name;
+            }
+        }
+
+        public override Type BaseType
+        {
+            get
+            {
+                
+                return _BaseType;
+            }
+        }
+
+        public override string Namespace
+        {
+            get
+            {
+                
+                return _Namespace;
+            }
+        }
+
+        public override string FullName
+        {
+            get
+            { 
+                
+                return string.Format("{0}.{1}", _Namespace, _Name);
+            }
+        }
+
+        public override object[] GetCustomAttributes(Type attributeType, bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        public override object[] GetCustomAttributes(bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        // TODO: what is this?
+        protected override System.Reflection.TypeAttributes GetAttributeFlagsImpl()
+        {
+
+            return TypeAttributes.Class | TypeAttributes.Public | (TypeAttributes)0x40000000; // add the special flag to indicate an erased type, see TypeProviderTypeAttributes
+        }
+
+        // This one seems to be invoked when in IDE, I type something like:
+        // let _ = typeof<N.
+        // In this case => no constructors
+        public override System.Reflection.ConstructorInfo[] GetConstructors(System.Reflection.BindingFlags bindingAttr)
+        {
+            
+            // According to the spec, we should only expect these 4, so we guard against that here!
+            Debug.Assert(bindingAttr == (BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly), "bindingAttr has value not according to the spec!");
+            if (_Ctor1!=null) 
+                return new System.Reflection.ConstructorInfo[] { _Ctor1 };
+            else
+                return new System.Reflection.ConstructorInfo[] { };
+        }
+
+        // When you start typing more interesting things like...
+        // let a = N.T.M()
+        // this one gets invoked...
+        public override System.Reflection.MethodInfo[] GetMethods(System.Reflection.BindingFlags bindingAttr)
+        {
+            
+            // According to the spec, we should only expect these 4, so we guard against that here!
+            Debug.Assert(bindingAttr == (BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly), "bindingAttr has value not according to the spec!");
+            return new[] { _Method1 };
+        }
+
+        // This method is called when in the source file we have something like:
+        // - N.T.StaticProp 
+        // (most likely also when we have an instance prop...)
+        // name -> "StaticProp"
+        protected override System.Reflection.PropertyInfo GetPropertyImpl(string name, System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder binder, Type returnType, Type[] types, System.Reflection.ParameterModifier[] modifiers)
+        {
+            
+            // According to the spec, we should only expect these 4, so we guard against that here!
+            Debug.Assert(bindingAttr == (BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly), "bindingAttr has value not according to the spec!");
+            Debug.Assert(binder == null && returnType == null && types == null && modifiers == null, "One of binder, returnType, types, or modifiers was not null");
+            if (name == _Property1.Name)
+                return _Property1;
+            else
+                return null;
+        }
+
+        // Advertise our property...
+        // I think that is this one returns an empty array => you don't get intellisense/autocomplete in IDE/FSI
+        public override System.Reflection.PropertyInfo[] GetProperties(System.Reflection.BindingFlags bindingAttr)
+        {
+            
+            // According to the spec, we should only expect these 4, so we guard against that here!
+            Debug.Assert(bindingAttr == (BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly), "bindingAttr has value not according to the spec!");
+            return new PropertyInfo[] { _Property1 };
+        }
+
+        // No fields...
+        public override System.Reflection.FieldInfo GetField(string name, System.Reflection.BindingFlags bindingAttr)
+        {
+            
+            // According to the spec, we should only expect these 4, so we guard against that here!
+            Debug.Assert(bindingAttr == (BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly), "bindingAttr has value not according to the spec!");
+            return null;
+        }
+
+        public override System.Reflection.FieldInfo[] GetFields(System.Reflection.BindingFlags bindingAttr)
+        {
+            
+            // According to the spec, we should only expect these 4, so we guard against that here!
+            Debug.Assert(bindingAttr == (BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly), "bindingAttr has value not according to the spec!");
+            return new System.Reflection.FieldInfo[] { };
+        }
+
+        // Events
+        public override System.Reflection.EventInfo GetEvent(string name, System.Reflection.BindingFlags bindingAttr)
+        {
+            
+            // According to the spec, we should only expect these 4, so we guard against that here!
+            Debug.Assert(bindingAttr == (BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly), "bindingAttr has value not according to the spec!");
+            if (_Event1 != null && _Event1.Name == name)
+                return _Event1;
+            else
+                return null;
+        }
+
+        // Events...
+        public override System.Reflection.EventInfo[] GetEvents(System.Reflection.BindingFlags bindingAttr)
+        {
+            
+            return _Event1 != null ? new [] { _Event1 } : new System.Reflection.EventInfo[] { };
+        }
+
+        // TODO: according to the spec, this should not be invoked... instead it seems like it may be invoked...
+        //       ?? I have no idea what this is used for... ??
+        public override Type UnderlyingSystemType
+        {
+            get
+            {
+                
+                return null;
+            }
+        }
+
+        // According to the spec, this should always be 'false'
+        protected override bool IsArrayImpl()
+        {
+            
+            return false;    
+        }
+
+        // No interfaces...
+        public override Type[] GetInterfaces()
+        {
+            
+            return new Type[] { };
+        }
+
+        // No nested type
+        // This method is invoked on the type 'T', e.g.:
+        //    let _ = N.T.M
+        // to figure out if M is a nested type.
+        public override Type GetNestedType(string name, System.Reflection.BindingFlags bindingAttr)
+        {
+            
+            return null;
+        }
+        public override Type[] GetNestedTypes(System.Reflection.BindingFlags bindingAttr)
+        {
+            
+            // According to the spec, we should only expect these 4, so we guard against that here!
+            Debug.Assert(bindingAttr == (BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly), "bindingAttr has value not according to the spec!");
+            return new Type[] { };
+        }
+
+        // This one is invoked when the type has a .ctor 
+        // and the code looks like
+        // let _ = new N.T()
+        // for example.
+        // It was observed that the
+        // TODO: cover both cases!
+        public override bool IsGenericType
+        {
+            get
+            {
+                
+                return _IsGenericType;
+            }
+        }
+
+        // This is invoked if the IsGenericType is true
+        public override Type[] GetGenericArguments()
+        {
+            
+            if (_IsGenericType)
+                return new Type[] { typeof(int), typeof(decimal), typeof(System.Guid) };        // This is currently triggering an ICE...
+            else
+            {
+                Debug.Assert(false, "Why are we here?");
+                throw new NotImplementedException();
+            }
+
+        }
+
+        // This one seems to be invoked when compiling something like
+        // let a = new N.T()
+        // Let's just stay away from generics...
+        public override bool IsGenericTypeDefinition
+        {
+            get
+            {
+                
+                return _IsGenericType;
+            }
+        }
+
+        // This one seems to be invoked when compiling something like
+        // let a = new N.T()
+        // Let's just stay away from generics...
+        public override bool ContainsGenericParameters
+        {
+            get
+            {
+                
+                return _IsGenericType;
+            }
+        }
+
+        // This one seems to be checked when in IDE.
+        // let b = N.T(
+        protected override bool IsValueTypeImpl()
+        {
+            
+            return _IsValueType;
+        }
+
+        // This one seems to be checked when in IDE.
+        // let b = N.T(
+        protected override bool IsByRefImpl()
+        {
+            
+            return _IsByRef;
+        }
+
+        // This one seems to be checked when in IDE.
+        // let b = N.T(
+        public override bool IsEnum
+        {
+            get
+            {
+                
+                return _IsEnum;
+            }
+        }
+
+        // This one seems to be checked when in IDE.
+        // let b = N.T(
+        protected override bool IsPointerImpl()
+        {
+            
+            return _IsPointer;
+        }
+
+        public override string AssemblyQualifiedName
+        {
+            get 
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override Guid GUID
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        protected override System.Reflection.ConstructorInfo GetConstructorImpl(System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder binder, System.Reflection.CallingConventions callConvention, Type[] types, System.Reflection.ParameterModifier[] modifiers)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override Type GetElementType()
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override Type GetInterface(string name, bool ignoreCase)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override System.Reflection.MemberInfo[] GetMembers(System.Reflection.BindingFlags bindingAttr)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        protected override System.Reflection.MethodInfo GetMethodImpl(string name, System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder binder, System.Reflection.CallingConventions callConvention, Type[] types, System.Reflection.ParameterModifier[] modifiers)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        protected override bool HasElementTypeImpl()
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override object InvokeMember(string name, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, object target, object[] args, System.Reflection.ParameterModifier[] modifiers, System.Globalization.CultureInfo culture, string[] namedParameters)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        protected override bool IsCOMObjectImpl()
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        protected override bool IsPrimitiveImpl()
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override System.Reflection.Module Module
+        {
+            get {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override bool IsDefined(Type attributeType, bool inherit)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override MethodBase DeclaringMethod
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.DeclaringMethod;
+            }
+        }
+
+        // This one is invoked by the F# compiler!
+        public override Type DeclaringType
+        {
+            get
+            {
+                
+                return null; // base.DeclaringType;
+            }
+        }
+
+        public override Type[] FindInterfaces(TypeFilter filter, object filterCriteria)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.FindInterfaces(filter, filterCriteria);
+        }
+
+        public override MemberInfo[] FindMembers(MemberTypes memberType, BindingFlags bindingAttr, MemberFilter filter, object filterCriteria)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.FindMembers(memberType, bindingAttr, filter, filterCriteria);
+        }
+
+        public override GenericParameterAttributes GenericParameterAttributes
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.GenericParameterAttributes;
+            }
+        }
+
+        public override int GenericParameterPosition
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.GenericParameterPosition;
+            }
+        }
+
+        public override int GetArrayRank()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetArrayRank();
+        }
+
+        public override MemberInfo[] GetDefaultMembers()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetDefaultMembers();
+        }
+
+        public override string GetEnumName(object value)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetEnumName(value);
+        }
+
+        public override string[] GetEnumNames()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetEnumNames();
+        }
+
+        public override Type GetEnumUnderlyingType()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetEnumUnderlyingType();
+        }
+
+        public override Array GetEnumValues()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetEnumValues();
+        }
+
+        public override EventInfo[] GetEvents()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetEvents();
+        }
+
+        public override Type[] GetGenericParameterConstraints()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetGenericParameterConstraints();
+        }
+
+        public override Type GetGenericTypeDefinition()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetGenericTypeDefinition();
+        }
+
+        public override InterfaceMapping GetInterfaceMap(Type interfaceType)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetInterfaceMap(interfaceType);
+        }
+
+        public override MemberInfo[] GetMember(string name, BindingFlags bindingAttr)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetMember(name, bindingAttr);
+        }
+
+        public override MemberInfo[] GetMember(string name, MemberTypes type, BindingFlags bindingAttr)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetMember(name, type, bindingAttr);
+        }
+
+        protected override TypeCode GetTypeCodeImpl()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetTypeCodeImpl();
+        }
+
+        public override bool IsAssignableFrom(Type c)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.IsAssignableFrom(c);
+        }
+
+        protected override bool IsContextfulImpl()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.IsContextfulImpl();
+        }
+
+        public override bool IsEnumDefined(object value)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.IsEnumDefined(value);
+        }
+
+        public override bool IsEquivalentTo(Type other)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.IsEquivalentTo(other);
+        }
+
+        public override bool IsGenericParameter
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.IsGenericParameter;
+            }
+        }
+
+        public override bool IsInstanceOfType(object o)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.IsInstanceOfType(o);
+        }
+
+        protected override bool IsMarshalByRefImpl()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.IsMarshalByRefImpl();
+        }
+
+        public override bool IsSecurityCritical
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.IsSecurityCritical;
+            }
+        }
+
+        public override bool IsSecuritySafeCritical
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.IsSecuritySafeCritical;
+            }
+        }
+
+        public override bool IsSecurityTransparent
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.IsSecurityTransparent;
+            }
+        }
+
+        public override bool IsSerializable
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.IsSerializable;
+            }
+        }
+
+        public override bool IsSubclassOf(Type c)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.IsSubclassOf(c);
+        }
+
+        public override Type MakeArrayType()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.MakeArrayType();
+        }
+
+        public override Type MakeArrayType(int rank)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.MakeArrayType(rank);
+        }
+
+        public override Type MakeByRefType()
+        {
+            return base.MakeByRefType();
+        }
+
+        public override Type MakeGenericType(params Type[] typeArguments)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.MakeGenericType(typeArguments);
+        }
+
+        public override Type MakePointerType()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.MakePointerType();
+        }
+
+        public override MemberTypes MemberType
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.MemberType;
+            }
+        }
+
+        public override int MetadataToken
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.MetadataToken;
+            }
+        }
+
+        public override Type ReflectedType
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.ReflectedType;
+            }
+        }
+
+        public override System.Runtime.InteropServices.StructLayoutAttribute StructLayoutAttribute
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.StructLayoutAttribute;
+            }
+        }
+
+        public override RuntimeTypeHandle TypeHandle
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.TypeHandle;
+            }
+        }
+
+        public override string ToString()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.ToString();
+        }
+
+        public override IList<CustomAttributeData> GetCustomAttributesData()
+        {
+            var attrs = new List<CustomAttributeData>();
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderXmlDocAttribute("This is a synthetic type created by me!")));
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderDefinitionLocationAttribute() { Column = 21, FilePath = "File.fs", Line = 50 }));
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderEditorHideMethodsAttribute()));
+            return attrs;
+        }
+
+    }
+
+}
diff --git a/vsintegration/src/unittests/Resources.MockTypeProviders/DefinitionLocationAttributeLineDoesnotExist/DefinitionLocationAttributeLineDoesnotExist.csproj b/vsintegration/src/unittests/Resources.MockTypeProviders/DefinitionLocationAttributeLineDoesnotExist/DefinitionLocationAttributeLineDoesnotExist.csproj
new file mode 100644
index 0000000..46b2a18
--- /dev/null
+++ b/vsintegration/src/unittests/Resources.MockTypeProviders/DefinitionLocationAttributeLineDoesnotExist/DefinitionLocationAttributeLineDoesnotExist.csproj
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information. -->
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <FSharpSourcesRoot>..\..\..\..\..\src</FSharpSourcesRoot>
+    <ProjectLanguage>CSharp</ProjectLanguage>
+  </PropertyGroup>
+  <Import Project="$(FSharpSourcesRoot)\FSharpSource.settings.targets" />
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{F47196DC-186D-4055-BAF2-658282A12F33}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AssemblyName>DefinitionLocationAttributeLineDoesnotExist</AssemblyName>
+    <WarningLevel>4</WarningLevel>
+    <NoWarn>0169;0067</NoWarn>
+    <DefineConstants>DEBUG;TRACE;$(DefineConstants)</DefineConstants>
+    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+    <OutputPath>$(FSharpSourcesRoot)\..\$(Configuration)\$(TargetFramework)\bin\UnitTestsResources\MockTypeProviders</OutputPath>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+    <ProjectReference Include="$(FSharpSourcesRoot)\fsharp\FSharp.Core\FSharp.Core.fsproj">
+      <Project>{DED3BBD7-53F4-428A-8C9F-27968E768605}</Project>
+      <Name>FSharp.Core</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="ArtificalEventInfo.cs" />
+    <Compile Include="ArtificialConstructorInfo.cs" />
+    <Compile Include="ArtificialMethodInfo.cs" />
+    <Compile Include="ArtificialParamInfo.cs" />
+    <Compile Include="ArtificialType.cs" />
+    <Compile Include="ArtificialPropertyInfo.cs" />
+    <Compile Include="TypeProviderInCSharp.cs" />
+    <Compile Include="..\Helpers.cs" />
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+</Project>
diff --git a/vsintegration/src/unittests/Resources.MockTypeProviders/DefinitionLocationAttributeLineDoesnotExist/TypeProviderInCSharp.cs b/vsintegration/src/unittests/Resources.MockTypeProviders/DefinitionLocationAttributeLineDoesnotExist/TypeProviderInCSharp.cs
new file mode 100644
index 0000000..d381f9e
--- /dev/null
+++ b/vsintegration/src/unittests/Resources.MockTypeProviders/DefinitionLocationAttributeLineDoesnotExist/TypeProviderInCSharp.cs
@@ -0,0 +1,140 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Microsoft.FSharp.Core.CompilerServices;
+using Microsoft.FSharp.Quotations;
+using System.Reflection;
+using System.Diagnostics;
+
+[assembly: TypeProviderAssembly()]
+
+namespace TypeProviderInCSharp
+{
+    //namespace N
+    //{
+    //    class S
+    //    {
+    //        public int instanceField;
+    //        public S(int x)
+    //        {
+    //            instanceField = x;
+    //        }
+    //    }
+    //}
+
+    class Namespace1 : IProvidedNamespace
+    {
+        const string _Namespace = "N";
+        const string _Name = "T";
+
+        // Type myType = new myType(typeof(N.S), "Bad.Name", typeof(Action), true);
+        Type myType = new ArtificialType(_Namespace, _Name, false, basetype: typeof(object), isValueType: false, isByRef: false, isEnum: false, IsPointer: false);
+
+        public IProvidedNamespace[] GetNestedNamespaces()
+        {
+
+            return new IProvidedNamespace[] { };
+        }
+
+        public Type[] GetTypes()
+        {
+
+            return new Type[] { myType };
+        }
+
+        public string NamespaceName
+        {
+            get { return _Namespace; }
+        }
+
+        public Type ResolveTypeName(string typeName)
+        {
+
+            if (typeName == _Name)
+            {
+                return myType;
+            }
+            return null;
+        }
+    }
+
+    [TypeProvider()]
+    public class TypeProvider : ITypeProvider
+    {
+        void IDisposable.Dispose()
+        {
+        }
+        private void Param(int staticParam)
+        {
+        }
+
+        public Type ApplyStaticArguments(Type typeWithoutArguments, string[] typeNameWithArguments, object[] staticArguments)
+        {
+            //Console.WriteLine("Hello from ApplyStaticArguments");
+            //var n = new myType(typeof(N.S), "S,\"1\"", typeof(object), false);
+            //return n;
+
+            return null;
+        }
+
+        public FSharpExpr GetInvokerExpression(System.Reflection.MethodBase syntheticMethodBase, FSharpExpr[] parameters)
+        {
+
+            if (syntheticMethodBase is System.Reflection.ConstructorInfo)
+            {
+                var ac = syntheticMethodBase as ArtificialConstructorInfo;
+                if (ac.DeclaringType.FullName == "N.T")
+                {
+                    return FSharpExpr.DefaultValue(ac.DeclaringType.BaseType);
+                }
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+            else if (syntheticMethodBase is System.Reflection.MethodInfo)
+            {
+                var am = syntheticMethodBase as ArtificialMethodInfo;
+                if (am.DeclaringType.FullName == "N.T" && am.Name == "M")
+                {
+                    return FSharpExpr.Lambda(FSharpVar.Global("", typeof(int[])), FSharpExpr.Value<int[]>(new[] { 1, 2, 3 }));
+                }
+                else if (am.DeclaringType.FullName == "N.T" && am.Name == "get_StaticProp")
+                {
+                    return FSharpExpr.Lambda(FSharpVar.Global("", typeof(decimal)), FSharpExpr.Value<decimal>(4.2M));
+                }
+                else
+                {
+                    Debug.Assert(false, "NYI");
+                    throw new NotImplementedException();
+                }
+            }
+            else
+            {
+                Debug.Assert(false, "GetInvokerExpression() invoked with neither ConstructorInfo nor MethodInfo!");
+                return null;
+            }
+            //Expression<Func<S>> e = () => new S(9);
+            //return e.Body;
+
+            //throw new NotImplementedException();
+        }
+
+        public IProvidedNamespace[] GetNamespaces()
+        {
+
+            return new IProvidedNamespace[] { new Namespace1() };
+        }
+
+        public System.Reflection.ParameterInfo[] GetStaticParameters(Type typeWithoutArguments)
+        {
+
+            // No StaticParams
+            return new ParameterInfo[] { /* new myParameterInfo() */ };
+        }
+
+        public event EventHandler Invalidate;
+        public byte[] GetGeneratedAssemblyContents(Assembly assembly) { throw (new Exception("GetGeneratedAssemblyContents - only erased types were provided!!")); }
+    }
+}
diff --git a/vsintegration/src/unittests/Resources.MockTypeProviders/DefinitionLocationAttributeWithSpaceInTheType/ArtificalEventInfo.cs b/vsintegration/src/unittests/Resources.MockTypeProviders/DefinitionLocationAttributeWithSpaceInTheType/ArtificalEventInfo.cs
new file mode 100644
index 0000000..f51b398
--- /dev/null
+++ b/vsintegration/src/unittests/Resources.MockTypeProviders/DefinitionLocationAttributeWithSpaceInTheType/ArtificalEventInfo.cs
@@ -0,0 +1,131 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Reflection;
+using Microsoft.FSharp.Core.CompilerServices;
+
+namespace TypeProviderInCSharp
+{
+    class ArtificalEventInfo : EventInfo
+    {
+        string _Name;
+        Type _DeclaringType;
+        Type _EventHandleType;
+        MethodInfo _AddMethod;
+        MethodInfo _RemoveMethod;
+
+        public ArtificalEventInfo(string Name, Type DeclaringType, Type EventHandleType)
+        {
+            _Name = Name;
+            _DeclaringType = DeclaringType;
+            _EventHandleType = EventHandleType;
+
+            _AddMethod = new ArtificialMethodInfo("add_" + _Name, _DeclaringType, typeof(void), MethodAttributes.FamANDAssem | MethodAttributes.Family | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.Public);
+            _RemoveMethod = new ArtificialMethodInfo("remove_" + _Name, _DeclaringType, typeof(void), MethodAttributes.FamANDAssem | MethodAttributes.Family | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.Public);
+        }
+
+        // This one is invoked
+        public override Type EventHandlerType
+        {
+            get
+            {
+                
+                return _EventHandleType;
+            }
+        }
+
+        public override string Name
+        {
+            get 
+            { 
+                
+                return _Name;
+            }
+        }
+
+        public override Type DeclaringType
+        {
+            get
+            {
+                
+                return _DeclaringType;
+            }
+        }
+
+        // This one is needed
+        public override MethodInfo GetAddMethod(bool nonPublic)
+        {
+            
+            Debug.Assert(!nonPublic, "GetAddMethod() was called with nonPublic=true");
+            return _AddMethod;
+        }
+
+        // This one is needed
+        public override MethodInfo GetRemoveMethod(bool nonPublic)
+        {
+            
+            Debug.Assert(!nonPublic, "GetRemoveMethod() was called with nonPublic=true");
+            return _RemoveMethod;
+        }
+
+
+        public override object[] GetCustomAttributes(Type attributeType, bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        public override EventAttributes Attributes
+        {
+            get
+            {
+                
+                return EventAttributes.None;
+            }
+        }
+
+        public override MethodInfo GetRaiseMethod(bool nonPublic)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override object[] GetCustomAttributes(bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        public override bool IsDefined(Type attributeType, bool inherit)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override Type ReflectedType
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override IList<CustomAttributeData> GetCustomAttributesData()
+        {
+            var attrs = new List<CustomAttributeData>();
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderXmlDocAttribute(string.Format("This is a synthetic *event* created by me for {0}.{1}", this._DeclaringType.Namespace, this._DeclaringType.Name))));
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderDefinitionLocationAttribute() { Column = 21, FilePath = "File.fs", Line = 4 }));
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderEditorHideMethodsAttribute()));
+            return attrs;
+        }
+
+    }
+}
diff --git a/vsintegration/src/unittests/Resources.MockTypeProviders/DefinitionLocationAttributeWithSpaceInTheType/ArtificialConstructorInfo.cs b/vsintegration/src/unittests/Resources.MockTypeProviders/DefinitionLocationAttributeWithSpaceInTheType/ArtificialConstructorInfo.cs
new file mode 100644
index 0000000..5899d39
--- /dev/null
+++ b/vsintegration/src/unittests/Resources.MockTypeProviders/DefinitionLocationAttributeWithSpaceInTheType/ArtificialConstructorInfo.cs
@@ -0,0 +1,135 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Reflection;
+using Microsoft.FSharp.Core.CompilerServices;
+
+namespace TypeProviderInCSharp
+{
+    class ArtificialConstructorInfo : ConstructorInfo
+    {
+        Type _DeclaringType;
+        ParameterInfo[] _ParameterInfo;
+
+        public ArtificialConstructorInfo(Type DeclaringType, ParameterInfo[] ParamInfo)
+        {
+            _DeclaringType = DeclaringType;
+            _ParameterInfo = ParamInfo;
+        }
+
+        public override Type DeclaringType
+        {
+            get
+            {
+                
+                return _DeclaringType;
+            }
+        }
+
+        // This one is invoked
+        public override ParameterInfo[] GetParameters()
+        {
+            
+            return _ParameterInfo;
+        }
+
+        // This one is indeed invoked
+        // I believe we should always return ".ctor"
+        public override string Name
+        {
+            get
+            {
+                
+                return ".ctor";
+            }
+        }
+
+        // Does it matter what we return here?
+        // This property is definitely checked by the compiler in code like this:
+        // let _ = new N.T()
+        // I copied the attribute set from the .ctor of System.DateTime - the documentation on MSDN assumes that one is already familiar with
+        // what they mean (=totally useless, as often happens)
+        public override MethodAttributes Attributes
+        {
+            get
+            {
+                
+                return MethodAttributes.FamANDAssem | MethodAttributes.Family | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName;
+            }
+        }
+
+        public override object[] GetCustomAttributes(Type attributeType, bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        public override object Invoke(BindingFlags invokeAttr, Binder binder, object[] parameters, System.Globalization.CultureInfo culture)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override MethodImplAttributes GetMethodImplementationFlags()
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override object Invoke(object obj, BindingFlags invokeAttr, Binder binder, object[] parameters, System.Globalization.CultureInfo culture)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override RuntimeMethodHandle MethodHandle
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override object[] GetCustomAttributes(bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        public override bool IsDefined(Type attributeType, bool inherit)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override Type ReflectedType
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override IList<CustomAttributeData> GetCustomAttributesData()
+        {
+            var attrs = new List<CustomAttributeData>();
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderXmlDocAttribute(string.Format("This is a synthetic .ctor created by me for {0}.{1}", this._DeclaringType.Namespace, this._DeclaringType.Name))));
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderDefinitionLocationAttribute() { Column = 21, FilePath = "File.fs", Line = 3 }));
+            // attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderEditorHideMethodsAttribute()));
+            return attrs;
+        }
+
+    }
+}
diff --git a/vsintegration/src/unittests/Resources.MockTypeProviders/DefinitionLocationAttributeWithSpaceInTheType/ArtificialMethodInfo.cs b/vsintegration/src/unittests/Resources.MockTypeProviders/DefinitionLocationAttributeWithSpaceInTheType/ArtificialMethodInfo.cs
new file mode 100644
index 0000000..337af50
--- /dev/null
+++ b/vsintegration/src/unittests/Resources.MockTypeProviders/DefinitionLocationAttributeWithSpaceInTheType/ArtificialMethodInfo.cs
@@ -0,0 +1,168 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Reflection;
+using Microsoft.FSharp.Core.CompilerServices;
+
+namespace TypeProviderInCSharp
+{
+    class ArtificialMethodInfo : MethodInfo
+    {
+        string _Name;
+        Type _DeclaringType;
+        Type _ReturnType;
+        MethodAttributes _MethodAttributes;
+
+        public ArtificialMethodInfo(string Name, Type DeclaringType, Type ReturnType, MethodAttributes MethodAttributes)
+        {
+            _Name = Name;
+            _DeclaringType = DeclaringType;
+            _ReturnType = ReturnType;
+            _MethodAttributes = MethodAttributes;
+        }
+
+        public override string Name
+        {
+            get 
+            { 
+                
+                return _Name;
+            }
+        }
+
+        public override Type DeclaringType
+        {
+            get
+            {
+                
+                return _DeclaringType;
+            }
+        }
+
+        // Make the method Public and Static - 
+        // TODO: should be configurable in the ctor...
+        public override MethodAttributes Attributes
+        {
+            get
+            {
+                
+                return _MethodAttributes;
+            }
+        }
+
+        // No params
+        // TODO: should be configurable in the ctor...
+        public override ParameterInfo[] GetParameters()
+        {
+            
+            return new ParameterInfo[] {  };
+        }
+
+        public override ParameterInfo ReturnParameter
+        {
+            get
+            {
+                //
+                //var retvalpi = new ArtificialParamInfo(typeof(List<>), true);
+                //return retvalpi;
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+
+            }
+        }
+
+        public override Type ReturnType
+        {
+            get
+            {
+                
+                return _ReturnType;
+            }
+        }
+
+        public override MethodInfo GetBaseDefinition()
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override ICustomAttributeProvider ReturnTypeCustomAttributes
+        {
+            get 
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override MethodImplAttributes GetMethodImplementationFlags()
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override object Invoke(object obj, BindingFlags invokeAttr, Binder binder, object[] parameters, System.Globalization.CultureInfo culture)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override RuntimeMethodHandle MethodHandle
+        {
+            get 
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override object[] GetCustomAttributes(Type attributeType, bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        public override object[] GetCustomAttributes(bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        public override bool IsDefined(Type attributeType, bool inherit)
+        {
+            
+            Debug.Assert(false, "NYI"); 
+            throw new NotImplementedException();
+        }
+
+        public override Type ReflectedType
+        {
+            get 
+            { 
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override IList<CustomAttributeData> GetCustomAttributesData()
+        {
+            var attrs = new List<CustomAttributeData>();
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderXmlDocAttribute("This is a synthetic *method* created by me!!")));
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderDefinitionLocationAttribute() { Column = 21, FilePath = "File.fs", Line = 3 }));
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderEditorHideMethodsAttribute()));
+            return attrs;
+        }
+
+    }
+}
diff --git a/vsintegration/src/unittests/Resources.MockTypeProviders/DefinitionLocationAttributeWithSpaceInTheType/ArtificialParamInfo.cs b/vsintegration/src/unittests/Resources.MockTypeProviders/DefinitionLocationAttributeWithSpaceInTheType/ArtificialParamInfo.cs
new file mode 100644
index 0000000..6624f2d
--- /dev/null
+++ b/vsintegration/src/unittests/Resources.MockTypeProviders/DefinitionLocationAttributeWithSpaceInTheType/ArtificialParamInfo.cs
@@ -0,0 +1,156 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Reflection;
+using Microsoft.FSharp.Core.CompilerServices;
+
+namespace TypeProviderInCSharp
+{
+    public class ArtificialParamInfo : ParameterInfo
+    {
+        Type _type;
+        bool _isRetVal;
+
+        public ArtificialParamInfo(Type type, bool isRetVal)
+        {
+            _type = type;
+            _isRetVal = IsRetval;
+        }
+
+        // TODO: allow more customizations...
+        public override ParameterAttributes Attributes
+        {
+            get
+            {
+                return _isRetVal ? ParameterAttributes.Retval : ParameterAttributes.None;
+            }
+        }
+
+        public override Type ParameterType
+        {
+            get
+            {
+                return _type;
+            }
+        }
+
+        public override object DefaultValue
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override bool Equals(object obj)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override object[] GetCustomAttributes(bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        public override object[] GetCustomAttributes(Type attributeType, bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        public override int GetHashCode()
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override Type[] GetOptionalCustomModifiers()
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override Type[] GetRequiredCustomModifiers()
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override bool IsDefined(Type attributeType, bool inherit)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override MemberInfo Member
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override int MetadataToken
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override string Name
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override int Position
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override object RawDefaultValue
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override string ToString()
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+    }
+
+}
diff --git a/vsintegration/src/unittests/Resources.MockTypeProviders/DefinitionLocationAttributeWithSpaceInTheType/ArtificialPropertyInfo.cs b/vsintegration/src/unittests/Resources.MockTypeProviders/DefinitionLocationAttributeWithSpaceInTheType/ArtificialPropertyInfo.cs
new file mode 100644
index 0000000..7928039
--- /dev/null
+++ b/vsintegration/src/unittests/Resources.MockTypeProviders/DefinitionLocationAttributeWithSpaceInTheType/ArtificialPropertyInfo.cs
@@ -0,0 +1,181 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Reflection;
+using Microsoft.FSharp.Core.CompilerServices;
+
+namespace TypeProviderInCSharp
+{
+    class ArtificialPropertyInfo : PropertyInfo
+    {
+        string _Name;
+        bool _CanRead;
+        bool _CanWrite;
+        Type _DeclaringType;
+        Type _PropertyType;
+
+        MethodInfo _GetMethod;
+        MethodInfo _SetMethod;
+
+        public ArtificialPropertyInfo(string Name, Type DeclaringType, Type PropertyType, bool CanRead, bool CanWrite)
+        {
+            _Name = Name;
+            _DeclaringType = DeclaringType;
+            _PropertyType = PropertyType;
+            _CanRead = CanRead;
+            _CanWrite = CanWrite;
+
+            if(CanRead)
+                _GetMethod = new ArtificialMethodInfo("get_" + _Name, _DeclaringType, _PropertyType, MethodAttributes.Public | MethodAttributes.Static);
+            if (CanWrite)
+                _SetMethod = new ArtificialMethodInfo("set_" + _Name, _DeclaringType, null /* ?? */, MethodAttributes.Public | MethodAttributes.Static);
+
+        }
+
+        // The name of this property...
+        public override string Name
+        {
+            get
+            {
+                
+                return _Name;
+            }
+        }
+
+        // Needed
+        public override bool CanRead
+        {
+            get
+            {
+                
+                return _CanRead;
+            }
+        }
+
+        // If CanRead is true, this one gets invoked.
+        public override MethodInfo GetGetMethod(bool nonPublic)
+        {
+            
+            Debug.Assert(!nonPublic, "GetGetMethod was invoked with nonPublic=true");
+            return _GetMethod;
+        }
+
+        // Why is this invoked?
+        public override ParameterInfo[] GetIndexParameters()
+        {
+            
+            return new ParameterInfo[] { /* new ArtificialParamInfo(typeof(int), isRetVal: false), new ArtificialParamInfo(typeof(decimal), isRetVal: false) */};
+        }
+
+        // If CanRead is false, this one gets invoked... without checking 'CanWrite' (?)
+        public override MethodInfo GetSetMethod(bool nonPublic)
+        {
+            
+            return _SetMethod;
+        }
+
+        public override bool CanWrite
+        {
+            get
+            {
+                
+                return _CanWrite;
+            }
+        }
+
+        // Interestingly enough, this one seems to be invoked only when I hover over the property in the IDE...
+        public override Type PropertyType
+        {
+            get
+            {
+                
+                return _PropertyType;
+            }
+        }
+
+        // Interestingly enough, this one seems to be invoked only when I hover over the property in the IDE...
+        public override Type DeclaringType
+        {
+            get
+            {
+                
+                return _DeclaringType;
+            }
+        }
+
+        public override object[] GetCustomAttributes(Type attributeType, bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+
+        public override PropertyAttributes Attributes
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override MethodInfo[] GetAccessors(bool nonPublic)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override object GetValue(object obj, BindingFlags invokeAttr, Binder binder, object[] index, System.Globalization.CultureInfo culture)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override void SetValue(object obj, object value, BindingFlags invokeAttr, Binder binder, object[] index, System.Globalization.CultureInfo culture)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override object[] GetCustomAttributes(bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        public override bool IsDefined(Type attributeType, bool inherit)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override Type ReflectedType
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override IList<CustomAttributeData> GetCustomAttributesData()
+        {
+            var attrs = new List<CustomAttributeData>();
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderXmlDocAttribute(string.Format("This is a synthetic *property* created by me for {0}.{1}", this._DeclaringType.Namespace, this._DeclaringType.Name))));
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderDefinitionLocationAttribute() { Column = 21, FilePath = "File.fs", Line = 3 }));
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderEditorHideMethodsAttribute()));
+            return attrs;
+        }
+
+    }
+}
diff --git a/vsintegration/src/unittests/Resources.MockTypeProviders/DefinitionLocationAttributeWithSpaceInTheType/ArtificialType.cs b/vsintegration/src/unittests/Resources.MockTypeProviders/DefinitionLocationAttributeWithSpaceInTheType/ArtificialType.cs
new file mode 100644
index 0000000..6778cd3
--- /dev/null
+++ b/vsintegration/src/unittests/Resources.MockTypeProviders/DefinitionLocationAttributeWithSpaceInTheType/ArtificialType.cs
@@ -0,0 +1,771 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Reflection;
+using Microsoft.FSharp.Core.CompilerServices;
+
+namespace TypeProviderInCSharp
+{
+    public class ArtificialType : Type
+    {
+        string _Namespace;
+        string _Name;
+        bool _IsGenericType;
+        bool _IsValueType;  // value type = not class / not interface
+        bool _IsByRef;      // is the value passed by reference?
+        bool _IsEnum;
+        bool _IsPointer;
+
+        Type _BaseType;
+        MethodInfo _Method1;
+        PropertyInfo _Property1;
+        EventInfo _Event1;
+        FieldInfo _Field1;
+        ConstructorInfo _Ctor1;
+
+        public ArtificialType(string @namespace, string name, bool isGenericType, Type basetype, bool isValueType, bool isByRef, bool isEnum, bool IsPointer)
+        {
+            _Name = name;
+            _Namespace = @namespace;
+            _IsGenericType = isGenericType;
+            _BaseType = basetype;
+            _IsValueType = isValueType;
+            _IsByRef = isByRef;
+            _IsEnum = isEnum;
+            _IsPointer = IsPointer;
+            _Method1 = new ArtificialMethodInfo("M", this, typeof(int[]), MethodAttributes.Public | MethodAttributes.Static);
+            _Property1 = new ArtificialPropertyInfo("StaticProp", this, typeof(decimal), true, false);
+            _Event1 = new ArtificalEventInfo("Event1", this, typeof(EventHandler));
+            _Ctor1 = new ArtificialConstructorInfo(this, new ParameterInfo[] {} );  // parameter-less ctor
+        }
+
+        public override System.Reflection.Assembly Assembly
+        {
+            get 
+            { 
+                
+                return Assembly.GetExecutingAssembly();
+            }
+        }
+
+        public override string Name
+        {
+            get 
+            { 
+                
+                return _Name;
+            }
+        }
+
+        public override Type BaseType
+        {
+            get
+            {
+                
+                return _BaseType;
+            }
+        }
+
+        public override string Namespace
+        {
+            get
+            {
+                
+                return _Namespace;
+            }
+        }
+
+        public override string FullName
+        {
+            get
+            { 
+                
+                return string.Format("{0}.{1}", _Namespace, _Name);
+            }
+        }
+
+        public override object[] GetCustomAttributes(Type attributeType, bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        public override object[] GetCustomAttributes(bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        // TODO: what is this?
+        protected override System.Reflection.TypeAttributes GetAttributeFlagsImpl()
+        {
+
+            return TypeAttributes.Class | TypeAttributes.Public | (TypeAttributes)0x40000000; // add the special flag to indicate an erased type, see TypeProviderTypeAttributes
+        }
+
+        // This one seems to be invoked when in IDE, I type something like:
+        // let _ = typeof<N.
+        // In this case => no constructors
+        public override System.Reflection.ConstructorInfo[] GetConstructors(System.Reflection.BindingFlags bindingAttr)
+        {
+            
+            // According to the spec, we should only expect these 4, so we guard against that here!
+            Debug.Assert(bindingAttr == (BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly), "bindingAttr has value not according to the spec!");
+            if (_Ctor1!=null) 
+                return new System.Reflection.ConstructorInfo[] { _Ctor1 };
+            else
+                return new System.Reflection.ConstructorInfo[] { };
+        }
+
+        // When you start typing more interesting things like...
+        // let a = N.T.M()
+        // this one gets invoked...
+        public override System.Reflection.MethodInfo[] GetMethods(System.Reflection.BindingFlags bindingAttr)
+        {
+            
+            // According to the spec, we should only expect these 4, so we guard against that here!
+            Debug.Assert(bindingAttr == (BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly), "bindingAttr has value not according to the spec!");
+            return new[] { _Method1 };
+        }
+
+        // This method is called when in the source file we have something like:
+        // - N.T.StaticProp 
+        // (most likely also when we have an instance prop...)
+        // name -> "StaticProp"
+        protected override System.Reflection.PropertyInfo GetPropertyImpl(string name, System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder binder, Type returnType, Type[] types, System.Reflection.ParameterModifier[] modifiers)
+        {
+            
+            // According to the spec, we should only expect these 4, so we guard against that here!
+            Debug.Assert(bindingAttr == (BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly), "bindingAttr has value not according to the spec!");
+            Debug.Assert(binder == null && returnType == null && types == null && modifiers == null, "One of binder, returnType, types, or modifiers was not null");
+            if (name == _Property1.Name)
+                return _Property1;
+            else
+                return null;
+        }
+
+        // Advertise our property...
+        // I think that is this one returns an empty array => you don't get intellisense/autocomplete in IDE/FSI
+        public override System.Reflection.PropertyInfo[] GetProperties(System.Reflection.BindingFlags bindingAttr)
+        {
+            
+            // According to the spec, we should only expect these 4, so we guard against that here!
+            Debug.Assert(bindingAttr == (BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly), "bindingAttr has value not according to the spec!");
+            return new PropertyInfo[] { _Property1 };
+        }
+
+        // No fields...
+        public override System.Reflection.FieldInfo GetField(string name, System.Reflection.BindingFlags bindingAttr)
+        {
+            
+            // According to the spec, we should only expect these 4, so we guard against that here!
+            Debug.Assert(bindingAttr == (BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly), "bindingAttr has value not according to the spec!");
+            return null;
+        }
+
+        public override System.Reflection.FieldInfo[] GetFields(System.Reflection.BindingFlags bindingAttr)
+        {
+            
+            // According to the spec, we should only expect these 4, so we guard against that here!
+            Debug.Assert(bindingAttr == (BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly), "bindingAttr has value not according to the spec!");
+            return new System.Reflection.FieldInfo[] { };
+        }
+
+        // Events
+        public override System.Reflection.EventInfo GetEvent(string name, System.Reflection.BindingFlags bindingAttr)
+        {
+            
+            // According to the spec, we should only expect these 4, so we guard against that here!
+            Debug.Assert(bindingAttr == (BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly), "bindingAttr has value not according to the spec!");
+            if (_Event1 != null && _Event1.Name == name)
+                return _Event1;
+            else
+                return null;
+        }
+
+        // Events...
+        public override System.Reflection.EventInfo[] GetEvents(System.Reflection.BindingFlags bindingAttr)
+        {
+            
+            return _Event1 != null ? new [] { _Event1 } : new System.Reflection.EventInfo[] { };
+        }
+
+        // TODO: according to the spec, this should not be invoked... instead it seems like it may be invoked...
+        //       ?? I have no idea what this is used for... ??
+        public override Type UnderlyingSystemType
+        {
+            get
+            {
+                
+                return null;
+            }
+        }
+
+        // According to the spec, this should always be 'false'
+        protected override bool IsArrayImpl()
+        {
+            
+            return false;    
+        }
+
+        // No interfaces...
+        public override Type[] GetInterfaces()
+        {
+            
+            return new Type[] { };
+        }
+
+        // No nested type
+        // This method is invoked on the type 'T', e.g.:
+        //    let _ = N.T.M
+        // to figure out if M is a nested type.
+        public override Type GetNestedType(string name, System.Reflection.BindingFlags bindingAttr)
+        {
+            
+            return null;
+        }
+        public override Type[] GetNestedTypes(System.Reflection.BindingFlags bindingAttr)
+        {
+            
+            // According to the spec, we should only expect these 4, so we guard against that here!
+            Debug.Assert(bindingAttr == (BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly), "bindingAttr has value not according to the spec!");
+            return new Type[] { };
+        }
+
+        // This one is invoked when the type has a .ctor 
+        // and the code looks like
+        // let _ = new N.T()
+        // for example.
+        // It was observed that the
+        // TODO: cover both cases!
+        public override bool IsGenericType
+        {
+            get
+            {
+                
+                return _IsGenericType;
+            }
+        }
+
+        // This is invoked if the IsGenericType is true
+        public override Type[] GetGenericArguments()
+        {
+            
+            if (_IsGenericType)
+                return new Type[] { typeof(int), typeof(decimal), typeof(System.Guid) };        // This is currently triggering an ICE...
+            else
+            {
+                Debug.Assert(false, "Why are we here?");
+                throw new NotImplementedException();
+            }
+
+        }
+
+        // This one seems to be invoked when compiling something like
+        // let a = new N.T()
+        // Let's just stay away from generics...
+        public override bool IsGenericTypeDefinition
+        {
+            get
+            {
+                
+                return _IsGenericType;
+            }
+        }
+
+        // This one seems to be invoked when compiling something like
+        // let a = new N.T()
+        // Let's just stay away from generics...
+        public override bool ContainsGenericParameters
+        {
+            get
+            {
+                
+                return _IsGenericType;
+            }
+        }
+
+        // This one seems to be checked when in IDE.
+        // let b = N.T(
+        protected override bool IsValueTypeImpl()
+        {
+            
+            return _IsValueType;
+        }
+
+        // This one seems to be checked when in IDE.
+        // let b = N.T(
+        protected override bool IsByRefImpl()
+        {
+            
+            return _IsByRef;
+        }
+
+        // This one seems to be checked when in IDE.
+        // let b = N.T(
+        public override bool IsEnum
+        {
+            get
+            {
+                
+                return _IsEnum;
+            }
+        }
+
+        // This one seems to be checked when in IDE.
+        // let b = N.T(
+        protected override bool IsPointerImpl()
+        {
+            
+            return _IsPointer;
+        }
+
+        public override string AssemblyQualifiedName
+        {
+            get 
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override Guid GUID
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        protected override System.Reflection.ConstructorInfo GetConstructorImpl(System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder binder, System.Reflection.CallingConventions callConvention, Type[] types, System.Reflection.ParameterModifier[] modifiers)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override Type GetElementType()
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override Type GetInterface(string name, bool ignoreCase)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override System.Reflection.MemberInfo[] GetMembers(System.Reflection.BindingFlags bindingAttr)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        protected override System.Reflection.MethodInfo GetMethodImpl(string name, System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder binder, System.Reflection.CallingConventions callConvention, Type[] types, System.Reflection.ParameterModifier[] modifiers)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        protected override bool HasElementTypeImpl()
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override object InvokeMember(string name, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, object target, object[] args, System.Reflection.ParameterModifier[] modifiers, System.Globalization.CultureInfo culture, string[] namedParameters)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        protected override bool IsCOMObjectImpl()
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        protected override bool IsPrimitiveImpl()
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override System.Reflection.Module Module
+        {
+            get {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override bool IsDefined(Type attributeType, bool inherit)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override MethodBase DeclaringMethod
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.DeclaringMethod;
+            }
+        }
+
+        // This one is invoked by the F# compiler!
+        public override Type DeclaringType
+        {
+            get
+            {
+                
+                return null; // base.DeclaringType;
+            }
+        }
+
+        public override Type[] FindInterfaces(TypeFilter filter, object filterCriteria)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.FindInterfaces(filter, filterCriteria);
+        }
+
+        public override MemberInfo[] FindMembers(MemberTypes memberType, BindingFlags bindingAttr, MemberFilter filter, object filterCriteria)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.FindMembers(memberType, bindingAttr, filter, filterCriteria);
+        }
+
+        public override GenericParameterAttributes GenericParameterAttributes
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.GenericParameterAttributes;
+            }
+        }
+
+        public override int GenericParameterPosition
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.GenericParameterPosition;
+            }
+        }
+
+        public override int GetArrayRank()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetArrayRank();
+        }
+
+        public override MemberInfo[] GetDefaultMembers()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetDefaultMembers();
+        }
+
+        public override string GetEnumName(object value)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetEnumName(value);
+        }
+
+        public override string[] GetEnumNames()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetEnumNames();
+        }
+
+        public override Type GetEnumUnderlyingType()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetEnumUnderlyingType();
+        }
+
+        public override Array GetEnumValues()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetEnumValues();
+        }
+
+        public override EventInfo[] GetEvents()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetEvents();
+        }
+
+        public override Type[] GetGenericParameterConstraints()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetGenericParameterConstraints();
+        }
+
+        public override Type GetGenericTypeDefinition()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetGenericTypeDefinition();
+        }
+
+        public override InterfaceMapping GetInterfaceMap(Type interfaceType)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetInterfaceMap(interfaceType);
+        }
+
+        public override MemberInfo[] GetMember(string name, BindingFlags bindingAttr)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetMember(name, bindingAttr);
+        }
+
+        public override MemberInfo[] GetMember(string name, MemberTypes type, BindingFlags bindingAttr)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetMember(name, type, bindingAttr);
+        }
+
+        protected override TypeCode GetTypeCodeImpl()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetTypeCodeImpl();
+        }
+
+        public override bool IsAssignableFrom(Type c)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.IsAssignableFrom(c);
+        }
+
+        protected override bool IsContextfulImpl()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.IsContextfulImpl();
+        }
+
+        public override bool IsEnumDefined(object value)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.IsEnumDefined(value);
+        }
+
+        public override bool IsEquivalentTo(Type other)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.IsEquivalentTo(other);
+        }
+
+        public override bool IsGenericParameter
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.IsGenericParameter;
+            }
+        }
+
+        public override bool IsInstanceOfType(object o)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.IsInstanceOfType(o);
+        }
+
+        protected override bool IsMarshalByRefImpl()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.IsMarshalByRefImpl();
+        }
+
+        public override bool IsSecurityCritical
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.IsSecurityCritical;
+            }
+        }
+
+        public override bool IsSecuritySafeCritical
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.IsSecuritySafeCritical;
+            }
+        }
+
+        public override bool IsSecurityTransparent
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.IsSecurityTransparent;
+            }
+        }
+
+        public override bool IsSerializable
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.IsSerializable;
+            }
+        }
+
+        public override bool IsSubclassOf(Type c)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.IsSubclassOf(c);
+        }
+
+        public override Type MakeArrayType()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.MakeArrayType();
+        }
+
+        public override Type MakeArrayType(int rank)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.MakeArrayType(rank);
+        }
+
+        public override Type MakeByRefType()
+        {
+            return base.MakeByRefType();
+        }
+
+        public override Type MakeGenericType(params Type[] typeArguments)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.MakeGenericType(typeArguments);
+        }
+
+        public override Type MakePointerType()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.MakePointerType();
+        }
+
+        public override MemberTypes MemberType
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.MemberType;
+            }
+        }
+
+        public override int MetadataToken
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.MetadataToken;
+            }
+        }
+
+        public override Type ReflectedType
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.ReflectedType;
+            }
+        }
+
+        public override System.Runtime.InteropServices.StructLayoutAttribute StructLayoutAttribute
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.StructLayoutAttribute;
+            }
+        }
+
+        public override RuntimeTypeHandle TypeHandle
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.TypeHandle;
+            }
+        }
+
+        public override string ToString()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.ToString();
+        }
+
+        public override IList<CustomAttributeData> GetCustomAttributesData()
+        {
+            var attrs = new List<CustomAttributeData>();
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderXmlDocAttribute("This is a synthetic type created by me!")));
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderDefinitionLocationAttribute() { Column = 21, FilePath = "File.fs", Line = 3 }));
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderEditorHideMethodsAttribute()));
+            return attrs;
+        }
+
+    }
+
+}
diff --git a/vsintegration/src/unittests/Resources.MockTypeProviders/DefinitionLocationAttributeWithSpaceInTheType/DefinitionLocationAttributeWithSpaceInTheType.csproj b/vsintegration/src/unittests/Resources.MockTypeProviders/DefinitionLocationAttributeWithSpaceInTheType/DefinitionLocationAttributeWithSpaceInTheType.csproj
new file mode 100644
index 0000000..335db19
--- /dev/null
+++ b/vsintegration/src/unittests/Resources.MockTypeProviders/DefinitionLocationAttributeWithSpaceInTheType/DefinitionLocationAttributeWithSpaceInTheType.csproj
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information. -->
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <FSharpSourcesRoot>..\..\..\..\..\src</FSharpSourcesRoot>
+    <ProjectLanguage>CSharp</ProjectLanguage>
+  </PropertyGroup>
+  <Import Project="$(FSharpSourcesRoot)\FSharpSource.settings.targets" />
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{D4C88934-5893-467E-A55C-A11ECD6479FE}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AssemblyName>DefinitionLocationAttributeWithSpaceInTheType</AssemblyName>
+    <WarningLevel>4</WarningLevel>
+    <NoWarn>0169;0067</NoWarn>
+    <DefineConstants>DEBUG;TRACE;$(DefineConstants)</DefineConstants>
+    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+    <OutputPath>$(FSharpSourcesRoot)\..\$(Configuration)\$(TargetFramework)\bin\UnitTestsResources\MockTypeProviders</OutputPath>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+    <ProjectReference Include="$(FSharpSourcesRoot)\fsharp\FSharp.Core\FSharp.Core.fsproj">
+      <Project>{DED3BBD7-53F4-428A-8C9F-27968E768605}</Project>
+      <Name>FSharp.Core</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="ArtificalEventInfo.cs" />
+    <Compile Include="ArtificialConstructorInfo.cs" />
+    <Compile Include="ArtificialMethodInfo.cs" />
+    <Compile Include="ArtificialParamInfo.cs" />
+    <Compile Include="ArtificialType.cs" />
+    <Compile Include="ArtificialPropertyInfo.cs" />
+    <Compile Include="TypeProviderInCSharp.cs" />
+    <Compile Include="..\Helpers.cs" />
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+</Project>
+
diff --git a/vsintegration/src/unittests/Resources.MockTypeProviders/DefinitionLocationAttributeWithSpaceInTheType/TypeProviderInCSharp.cs b/vsintegration/src/unittests/Resources.MockTypeProviders/DefinitionLocationAttributeWithSpaceInTheType/TypeProviderInCSharp.cs
new file mode 100644
index 0000000..68d6745
--- /dev/null
+++ b/vsintegration/src/unittests/Resources.MockTypeProviders/DefinitionLocationAttributeWithSpaceInTheType/TypeProviderInCSharp.cs
@@ -0,0 +1,141 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Microsoft.FSharp.Core.CompilerServices;
+using Microsoft.FSharp.Quotations;
+using System.Reflection;
+using System.Diagnostics;
+
+[assembly: TypeProviderAssembly()]
+
+namespace TypeProviderInCSharp
+{
+    //namespace N
+    //{
+    //    class S
+    //    {
+    //        public int instanceField;
+    //        public S(int x)
+    //        {
+    //            instanceField = x;
+    //        }
+    //    }
+    //}
+
+    class Namespace1 : IProvidedNamespace
+    {
+        const string _Namespace = "N";
+        const string _Name = "T T";
+
+        // Type myType = new myType(typeof(N.S), "Bad.Name", typeof(Action), true);
+        Type myType = new ArtificialType(_Namespace, _Name, false, basetype: typeof(object), isValueType: false, isByRef: false, isEnum: false, IsPointer: false);
+
+        public IProvidedNamespace[] GetNestedNamespaces()
+        {
+            
+            return new IProvidedNamespace[] { };
+        }
+
+        public Type[] GetTypes()
+        {
+            
+            return new Type[] { myType };
+        }
+
+        public string NamespaceName
+        {
+            get { return _Namespace; }
+        }
+
+        public Type ResolveTypeName(string typeName)
+        {
+            
+            if (typeName == _Name)
+            {
+                return myType;
+            }
+            return null;
+        }
+    }
+
+    [TypeProvider()]
+    public class TypeProvider : ITypeProvider
+    {
+        void IDisposable.Dispose()
+        {
+        }
+        private void Param(int staticParam)
+        {
+        }
+
+        public Type ApplyStaticArguments(Type typeWithoutArguments, string[] typeNameWithArguments, object[] staticArguments)
+        {
+            //Console.WriteLine("Hello from ApplyStaticArguments");
+            //var n = new myType(typeof(N.S), "S,\"1\"", typeof(object), false);
+            //return n;
+            
+            return null;
+        }
+
+        public FSharpExpr GetInvokerExpression(System.Reflection.MethodBase syntheticMethodBase, FSharpExpr[] parameters)
+        {
+            
+            if (syntheticMethodBase is System.Reflection.ConstructorInfo)
+            {
+                var ac = syntheticMethodBase as ArtificialConstructorInfo;
+                if (ac.DeclaringType.FullName == "N.T")
+                {
+                    return FSharpExpr.DefaultValue(ac.DeclaringType.BaseType);
+                }
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+            else if (syntheticMethodBase is System.Reflection.MethodInfo)
+            {
+                var am = syntheticMethodBase as ArtificialMethodInfo;
+                if (am.DeclaringType.FullName == "N.T" && am.Name == "M")
+                {
+                    return FSharpExpr.Lambda(new FSharpVar("", typeof(int[]), null), FSharpExpr.Value<int[]>(new[] { 1, 2, 3 }));
+                }
+                else if (am.DeclaringType.FullName == "N.T" && am.Name == "get_StaticProp")
+                {
+                    // Expression<Func<decimal[]>> e = () => K().Select(x=>(decimal)x).ToArray();
+                    return FSharpExpr.Lambda(new FSharpVar("", typeof(decimal), null), FSharpExpr.Value<decimal>(4.2M));
+                }
+                else
+                {
+                    Debug.Assert(false, "NYI");
+                    throw new NotImplementedException();
+                }
+            }
+            else
+            {
+                Debug.Assert(false, "GetInvokerExpression() invoked with neither ConstructorInfo nor MethodInfo!");
+                return null;
+            }
+            //Expression<Func<S>> e = () => new S(9);
+            //return e.Body;
+ 
+            //throw new NotImplementedException();
+        }
+
+        public IProvidedNamespace[] GetNamespaces()
+        {
+            
+            return new IProvidedNamespace[] { new Namespace1() };
+        }
+
+        public System.Reflection.ParameterInfo[] GetStaticParameters(Type typeWithoutArguments)
+        {
+            
+            // No StaticParams
+            return new ParameterInfo[] { /* new myParameterInfo() */ };
+        }
+
+        public event EventHandler Invalidate;
+        public byte[] GetGeneratedAssemblyContents(Assembly assembly) { throw (new Exception("GetGeneratedAssemblyContents - only erased types were provided!!")); }
+    }
+}
diff --git a/vsintegration/src/unittests/Resources.MockTypeProviders/DummyProviderForLanguageServiceTesting/DummyProviderForLanguageServiceTesting.fs b/vsintegration/src/unittests/Resources.MockTypeProviders/DummyProviderForLanguageServiceTesting/DummyProviderForLanguageServiceTesting.fs
new file mode 100644
index 0000000..b82da3d
--- /dev/null
+++ b/vsintegration/src/unittests/Resources.MockTypeProviders/DummyProviderForLanguageServiceTesting/DummyProviderForLanguageServiceTesting.fs
@@ -0,0 +1,426 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+namespace DummyProviderForLanguageServiceTesting 
+
+open Microsoft.FSharp.Core.CompilerServices
+open Microsoft.FSharp.TypeProvider.Emit
+open System.Linq.Expressions
+
+// Runtime methods, these are called instead of “erased” methods
+type RuntimeAPI = 
+    static member Convert(x:float) : decimal = decimal x
+    static member AddInt(x:int) = x+1
+    static member AddInt(x:int,y:int) = x+y
+    static member Identity(x : string) = x
+    static member IdentityInt(x : int) = x
+
+// Linq Expression functions for erased methods calls.
+module InvokeAPI = 
+    let addIntX (args : Quotations.Expr list) =
+        match Seq.length args with
+        | 1 -> <@@ RuntimeAPI.AddInt %%args.[0] @@>
+        | 2 -> <@@ RuntimeAPI.AddInt (%%args.[0], %%args.[1]) @@>
+        | _ -> failwithf "addIntX: expect arity 1 or 2 (got %d)" (Seq.length args)
+
+    let instanceX (args:Quotations.Expr list) =
+        match Seq.length args with
+        | 2 -> <@@ RuntimeAPI.IdentityInt (%%args.[1]) @@>
+        | _ -> failwithf "instanceX: expect arity 2 (got %d)" (Seq.length args)
+
+    let ctor (args:Quotations.Expr list) = 
+        match Seq.length args with
+        | 0 -> <@@ new System.Object() @@>
+        | _ -> failwithf "ctor:expect arity 1 (got %d)" (Seq.length args)
+
+module internal TPModule = 
+        
+    let namespaceName = "N1"    
+    let thisAssembly  = System.Reflection.Assembly.GetExecutingAssembly()
+
+    // A parametric type N1.T
+    let typeT = ProvidedTypeDefinition(thisAssembly,namespaceName,"T",Some typeof<System.Object>)
+
+    // Make an instantiation of the parametric type
+    // THe instantiated type has a static property that evaluates to the param passed
+    let instantiateParametricType (typeName:string) (args:System.Object[]) =
+        match args with
+        [| :? string as value; :? int as ignoredvalue; |] -> 
+            let typeParam = ProvidedTypeDefinition(thisAssembly,namespaceName, typeName, Some typeof<System.Object>)     
+            let propParam = ProvidedProperty("Param1", typeof<string>, 
+                                             IsStatic = true,
+                                             // A complicated was to basically return the constant value... Maybe there's a better/simpler way?
+                                             GetterCode = fun _ -> <@@ RuntimeAPI.Identity(value) @@>)
+            typeParam.AddMember(propParam :>System.Reflection.MemberInfo)
+            typeParam 
+        | _ -> failwithf "instantiateParametricType: unexpected params %A" args
+    
+    // N1.T<string, int>
+    typeT.DefineStaticParameters( [ ProvidedStaticParameter("Param1", typeof<string>); ProvidedStaticParameter("ParamIgnored", typeof<int>) ], instantiateParametricType )
+    typeT.AddXmlDoc("""<summary>N1.T type</summary><param name="Param1">Param1 of string</param><param name="ParamIgnored">Ignored</param>""")
+
+    // A non-parametric type N1.T1
+    let typeT1 = ProvidedTypeDefinition(thisAssembly,namespaceName,"T1",Some typeof<System.Object>)
+    
+        
+    // Two static methods: N1.T1.M1(int) and N1.T1.M2(int,int)
+    let methM1 = ProvidedMethod("M1",[ProvidedParameter("arg1", typeof<int>)],typeof<int>, IsStaticMethod=true, InvokeCode=InvokeAPI.addIntX)
+    let methM2 = ProvidedMethod("M2",[ProvidedParameter("arg1",typeof<int>);ProvidedParameter("arg2", typeof<int>)],typeof<int>, IsStaticMethod=true, InvokeCode=InvokeAPI.addIntX)
+
+    //one Instance method:N1.T1().IM1(int)
+    let methIM1 = ProvidedMethod("IM1",[ProvidedParameter("arg1", typeof<int>)],typeof<int>,IsStaticMethod=false,InvokeCode=InvokeAPI.instanceX)
+
+    // A method involving units-of-measure
+    let measures = ProvidedMeasureBuilder.Default
+    let kgAnnotation = measures.SI "kilogram"    // a measure
+    let hzAnnotation = measures.SI "hertz"       // a measure-abbreviation
+    let kg_per_hz_squared = measures.Ratio(kgAnnotation, measures.Square hzAnnotation)
+    let float_kg = measures.AnnotateType(typeof<double>,[kgAnnotation])
+    let decimal_kg_per_hz_squared = measures.AnnotateType(typeof<decimal>,[kg_per_hz_squared])
+    let nullable_decimal_kg_per_hz_squared = typedefof<System.Nullable<_>>.MakeGenericType [| decimal_kg_per_hz_squared |]
+
+    let methM3 = ProvidedMethod("MethodWithTypesInvolvingUnitsOfMeasure",[ProvidedParameter("arg1", float_kg)],nullable_decimal_kg_per_hz_squared, IsStaticMethod=true, InvokeCode=(fun args -> <@@ RuntimeAPI.Convert(%%(args.[0])) @@> ))
+
+    // an instance method using a conditional expression
+    let methM4 = ProvidedMethod("MethodWithErasedCodeUsingConditional",[],typeof<int>,IsStaticMethod=false,InvokeCode=(fun _ -> <@@ if true then 1 else 2 @@>))
+
+    // an instance method using a call and a type-as expression
+    let methM5 = ProvidedMethod("MethodWithErasedCodeUsingTypeAs",[],typeof<int>,IsStaticMethod=false,InvokeCode=(fun _ -> <@@ box 1 :?> int @@>))
+
+    // Three ctors
+    let ctorA = ProvidedConstructor([],InvokeCode=InvokeAPI.ctor)
+    let ctorB = ProvidedConstructor([ProvidedParameter("arg1",typeof<double>)])
+    let ctorC = ProvidedConstructor([ProvidedParameter("arg1",typeof<int>); ProvidedParameter("arg2",typeof<char>)])
+
+    typeT1.AddMember methM1
+    typeT1.AddMember methM2
+    typeT1.AddMember methIM1
+    typeT1.AddMember methM3
+    typeT1.AddMember methM4
+    typeT1.AddMember methM5
+    typeT1.AddMember ctorA
+    typeT1.AddMember ctorB
+    typeT1.AddMember ctorC
+
+    // a nested type
+    typeT1.AddMember <| ProvidedTypeDefinition("SomeNestedType", Some typeof<obj>)
+
+    let typeWithNestedTypes = ProvidedTypeDefinition(thisAssembly,namespaceName,"TypeWithNestedTypes", Some typeof<System.Object>)
+    typeWithNestedTypes.AddMember <| ProvidedTypeDefinition("X", Some typeof<obj>)
+    typeWithNestedTypes.AddMember <| ProvidedTypeDefinition("Z", Some typeof<obj>)
+    typeWithNestedTypes.AddMember <| ProvidedTypeDefinition("A", Some typeof<obj>)
+
+    let types = [ typeT1 ; typeT; typeWithNestedTypes ]
+
+// Used by unit testing to check that Dispose is being called on the type provider
+module GlobalCounters = 
+    let mutable creations = 0
+    let mutable disposals = 0
+    let GetTotalCreations() = creations
+    let GetTotalDisposals() = disposals
+
+
+[<TypeProvider>]
+type HelloWorldProvider() = 
+    inherit TypeProviderForNamespaces(TPModule.namespaceName,TPModule.types)
+    do GlobalCounters.creations <- GlobalCounters.creations + 1                         
+    let mutable disposed = false
+    interface System.IDisposable with 
+        member x.Dispose() = 
+            System.Diagnostics.Debug.Assert(not disposed)
+            disposed <- true
+            GlobalCounters.disposals <- GlobalCounters.disposals + 1                         
+            if GlobalCounters.disposals % 5 = 0 then failwith "simulate random error during disposal"
+
+
+// implementation of a poorly behaving TP that sleeps for various numbers of seconds when traversing into members.
+// simulates high network-latency, for testing VS robustness against badly-behaved providers.
+module internal SlowIntelliSenseTPModule = 
+        
+    let namespaceName = "SlowIntelliSense"    
+    let thisAssembly  = System.Reflection.Assembly.GetExecutingAssembly()
+
+    let typeT = ProvidedTypeDefinition(thisAssembly,namespaceName,"T",Some typeof<System.Object>)
+    let methM1 = ProvidedMethod("M1",[ProvidedParameter("arg1", typeof<int>)],typeof<int>, IsStaticMethod=true, InvokeCode=InvokeAPI.addIntX)
+    typeT.AddMember methM1
+
+    let rec populate(t:ProvidedTypeDefinition, millisDelay:int) =
+        t.AddMembersDelayed(fun() ->
+                System.Threading.Thread.Sleep(millisDelay)
+                // it is best for the first alphabetical to be zero-delay, as we immediately try to fetch its doc tip (which includes nested members)
+                let a = new ProvidedTypeDefinition("AZero", Some typeof<obj>)
+                populate(a, 0)
+                let e = new ProvidedTypeDefinition("Six", Some typeof<obj>)
+                populate(e, 6000)
+                let t = new ProvidedTypeDefinition("Three", Some typeof<obj>)
+                populate(t, 3000)
+                let z = new ProvidedTypeDefinition("Zero", Some typeof<obj>)
+                populate(z, 0)
+                [a;e;t;z]
+            )
+
+    typeT.AddMember(
+            let t = new ProvidedTypeDefinition("Zero", Some typeof<obj>)
+            populate(t,0)
+            t
+        )
+    let types = [ typeT ]
+
+[<TypeProvider>]
+type SlowIntellisenseProvider() = 
+    inherit TypeProviderForNamespaces(SlowIntelliSenseTPModule.namespaceName,SlowIntelliSenseTPModule.types)
+    do
+        ignore() // for breakpoint
+
+[<TypeProvider>]
+type ShowOffCreationTimeProvider() as this= 
+    inherit TypeProviderForNamespaces()
+    let namespaceName = "ShowOffCreationTime"    
+    let thisAssembly  = System.Reflection.Assembly.GetExecutingAssembly()
+
+    let typeT = ProvidedTypeDefinition(thisAssembly,namespaceName,"T",Some typeof<System.Object>)
+    let timeString = "CreatedAt" + System.DateTime.Now.ToLongTimeString()
+    let methM1 = ProvidedMethod(timeString,[ProvidedParameter("arg1", typeof<int>)],typeof<int>, IsStaticMethod=true, InvokeCode=InvokeAPI.addIntX)
+    let types = [ typeT ]
+
+    do
+        typeT.AddMember methM1
+        this.AddNamespace(namespaceName,types)
+
+
+module TypeProviderThatThrowsErrorsModule = 
+    type private Marker = interface end
+    let assembly = typeof<Marker>.Assembly
+    let rootNamespace = "TPErrors"
+    let types =
+        let t = ProvidedTypeDefinition(assembly, rootNamespace, "TP", Some typeof<obj>)
+        let parameter = ProvidedStaticParameter("N", typeof<int>)
+        t.DefineStaticParameters(
+            parameters = [parameter],
+            instantiationFunction = fun name args ->
+                match args with
+                | [|:? int as n|] when n > 0 ->
+                    let errors = Seq.init n (sprintf "Error %d" >> Failure)
+                    raise (System.AggregateException(errors))
+                | _ -> failwith "nonexpected"
+            )
+        [t]
+
+[<TypeProvider>]
+type TypeProviderThatThrowsErrors() = 
+    inherit TypeProviderForNamespaces(TypeProviderThatThrowsErrorsModule.rootNamespace, TypeProviderThatThrowsErrorsModule.types)
+
+module TypeProviderForTestingTuplesErasureModule = 
+    type private Marker = interface end
+    let assembly = typeof<Marker>.Assembly
+    
+    let rootNamespace = "TupleErasure"
+
+    let handle f = 
+        function
+        | [arg] -> f arg
+        | _ -> failwith "One argument expected"
+
+    let erasedTup = ProvidedTypeDefinition(assembly, rootNamespace, "TupleType", Some(typeof<int*string>))
+    erasedTup.AddMember(ProvidedConstructor([ProvidedParameter("tup", typeof<int * string>)], InvokeCode = handle (fun tup -> tup)))
+    erasedTup.AddMember(ProvidedProperty("SecondComponent", typeof<string>, GetterCode = handle (fun tup -> Quotations.Expr.TupleGet(tup, 1))))
+    
+    let objT = typedefof<int * string>.MakeGenericType(typeof<int>, erasedTup)
+    let erasedCompoundTup = ProvidedTypeDefinition(assembly, rootNamespace, "CompoundTupleType", Some(objT))
+    erasedCompoundTup.AddMember(ProvidedConstructor([ProvidedParameter("tup", objT)], InvokeCode = handle (fun tup -> tup)))
+    erasedCompoundTup.AddMember(ProvidedProperty("First", typeof<int>, GetterCode = handle (fun tup -> Quotations.Expr.TupleGet(tup, 0))))
+    erasedCompoundTup.AddMember(ProvidedProperty("Second", erasedTup, GetterCode = handle (fun tup -> Quotations.Expr.TupleGet(tup, 1))))
+
+[<TypeProvider>]
+type TypeProviderForTestingTuplesErasure() = 
+    inherit TypeProviderForNamespaces(TypeProviderForTestingTuplesErasureModule.rootNamespace, [TypeProviderForTestingTuplesErasureModule.erasedTup; TypeProviderForTestingTuplesErasureModule.erasedCompoundTup])
+
+module TypeProviderThatEmitsBadMethodsModule = 
+    let assembly = System.Reflection.Assembly.GetExecutingAssembly()
+    let rootNamespace = "BadMethods"
+    let arrayUser = ProvidedTypeDefinition(assembly, rootNamespace, "Arr", None)
+    let get = typeof<int[]>.GetMethod("Get")
+    let set = typeof<int[]>.GetMethod("Set")
+    let addr = typeof<int[]>.GetMethod("Address")
+    arrayUser.AddMember(
+        ProvidedMethod(
+            methodName = "GetFirstElement", 
+            parameters = [ProvidedParameter("array", typeof<int[]>)], 
+            returnType = typeof<int>, 
+            IsStaticMethod = true, 
+            InvokeCode = function [arr] -> Quotations.Expr.Call(arr, get, [Quotations.Expr.Value 0]) | _ -> failwith "One argument expected")
+        )
+    arrayUser.AddMember(
+        ProvidedMethod(
+            methodName = "SetFirstElement", 
+            parameters = [ProvidedParameter("array", typeof<int[]>); ProvidedParameter("val", typeof<int>)], 
+            returnType = typeof<unit>, 
+            IsStaticMethod = true, 
+            InvokeCode = function [arr; v] -> Quotations.Expr.Call(arr, set, [Quotations.Expr.Value 0; v]) | _ -> failwith "Two argument expected")
+        )
+    arrayUser.AddMember(
+        ProvidedMethod(
+            methodName = "AddressOfFirstElement", 
+            parameters = [ProvidedParameter("array", typeof<int[]>)], 
+            returnType = typeof<int>.MakeByRefType(), 
+            IsStaticMethod = true, 
+            InvokeCode = function [arr] -> Quotations.Expr.Call(arr, addr, [Quotations.Expr.Value 0]) | _ -> failwith "One argument expected")
+        )
+
+[<TypeProvider>]
+type TypeProviderThatEmitsBadMethods() = 
+    inherit TypeProviderForNamespaces(TypeProviderThatEmitsBadMethodsModule.rootNamespace, [TypeProviderThatEmitsBadMethodsModule.arrayUser])
+
+module TypeProvidersVisibilityChecks = 
+    let assembly = System.Reflection.Assembly.GetExecutingAssembly()
+
+    let Namespace = "GeneratedType"
+    let setMethodVisibility (m : ProvidedMethod) visibility = m.SetMethodAttrs((m.Attributes &&& ~~~System.Reflection.MethodAttributes.MemberAccessMask) ||| visibility)
+    let addMethod name value visibility (ty : ProvidedTypeDefinition) = 
+        let m = ProvidedMethod(name, [], value.GetType())
+        m.IsStaticMethod <- false
+        m.InvokeCode <- fun _ -> Quotations.Expr.Value(value, value.GetType())
+        setMethodVisibility m visibility
+        ty.AddMember m
+
+    let addGetProperty name value visibility (ty : ProvidedTypeDefinition) = 
+        let prop = ProvidedProperty(name, value.GetType())
+        ty.AddMember prop
+        prop.IsStatic <- false
+        prop.GetterCode <- fun _ -> Quotations.Expr.Value(value, value.GetType())
+        let m = prop.GetGetMethod() :?> ProvidedMethod
+        setMethodVisibility m visibility
+
+    let addLiteralField name value (ty : ProvidedTypeDefinition) = 
+        let f = ProvidedLiteralField(name, value.GetType(), value)
+        ty.AddMember f
+
+    let providedTy = 
+        let ty = ProvidedTypeDefinition(assembly, Namespace, "SampleType", Some typeof<obj>, IsErased=false)
+
+        /// unseal type
+        ty.SetAttributes(ty.Attributes &&& ~~~System.Reflection.TypeAttributes.Sealed)
+
+        // add public literal field
+        addLiteralField "PublicField" 100  ty
+        
+        // implicitly adds field
+        let ctor = ProvidedConstructor([ProvidedParameter("f", typeof<int>)])
+        ctor.InvokeCode <- fun _ -> <@@ () @@>
+        ty.AddMember ctor
+
+        // add properties
+        addGetProperty "PublicProp" 10 (System.Reflection.MethodAttributes.Public) ty
+        addGetProperty "ProtectedProp" 210 (System.Reflection.MethodAttributes.Family) ty
+        addGetProperty "PrivateProp" 310 (System.Reflection.MethodAttributes.Private) ty
+
+        // add methods
+        addMethod "PublicM" 510 (System.Reflection.MethodAttributes.Public) ty
+        addMethod "ProtectedM" 5210 (System.Reflection.MethodAttributes.Family) ty
+        addMethod "PrivateM" 5310 (System.Reflection.MethodAttributes.Private) ty
+        
+        ty.ConvertToGenerated(System.IO.Path.GetTempFileName() + ".dll")
+        ty
+
+    [<TypeProvider>]
+    type TypeProvider() = 
+        inherit TypeProviderForNamespaces(Namespace, [providedTy])
+
+module RegexTypeProvider =
+
+    open System.Text.RegularExpressions
+
+    [<TypeProvider>]
+    type public CheckedRegexProvider() as this =
+        inherit TypeProviderForNamespaces()
+
+        // Get the assembly and namespace used to house the provided types
+        let thisAssembly = System.Reflection.Assembly.GetExecutingAssembly()
+        let rootNamespace = "Samples.FSharp.RegexTypeProvider"
+        let baseTy = typeof<obj>
+        let staticParams = [ProvidedStaticParameter("pattern", typeof<string>)]
+
+        let regexTy = ProvidedTypeDefinition(thisAssembly, rootNamespace, "RegexTyped", Some baseTy)
+
+        do regexTy.DefineStaticParameters(
+            parameters=staticParams, 
+            instantiationFunction=(fun typeName parameterValues ->
+
+              match parameterValues with 
+              | [| :? string as pattern|] -> 
+                // Create an instance of the regular expression. 
+                //
+                // This will fail with System.ArgumentException if the regular expression is invalid. 
+                // The exception will excape the type provider and be reported in client code.
+                let r = System.Text.RegularExpressions.Regex(pattern)            
+
+                // Declare the typed regex provided type.
+                // The type erasure of this typs ia 'obj', even though the representation will always be a Regex
+                // This, combined with hiding the object methods, makes the IntelliSense experience simpler.
+                let ty = ProvidedTypeDefinition(
+                            thisAssembly, 
+                            rootNamespace, 
+                            typeName, 
+                            baseType = Some baseTy)
+
+                ty.AddXmlDoc "A strongly typed interface to the regular expression '%s'"
+
+                // Provide strongly typed version of Regex.IsMatch static method
+                let isMatch = ProvidedMethod(
+                                methodName = "IsMatch", 
+                                parameters = [ProvidedParameter("input", typeof<string>)], 
+                                returnType = typeof<bool>, 
+                                IsStaticMethod = true,
+                                InvokeCode = fun args -> <@@ Regex.IsMatch(%%args.[0], pattern) @@>) 
+
+                isMatch.AddXmlDoc "Indicates whether the regular expression finds a match in the specified input string"
+
+                ty.AddMember isMatch
+
+                // Provided type for matches
+                // Again, erase to obj even though the representation will always be a Match
+                let matchTy = ProvidedTypeDefinition(
+                                "MatchType", 
+                                baseType = Some baseTy, 
+                                HideObjectMethods = true)
+
+                // Nest the match type within parameterized Regex type
+                ty.AddMember matchTy
+        
+                // Add group properties to match type
+                for group in r.GetGroupNames() do
+                    // ignore the group named 0, which represents all input
+                    if group <> "0" then
+                        let prop = ProvidedProperty(
+                                    propertyName = group, 
+                                    propertyType = typeof<Group>, 
+                                    GetterCode = fun args -> <@@ ((%%args.[0]:obj) :?> Match).Groups.[group] @@>)
+                        prop.AddXmlDoc(sprintf @"Gets the ""%s"" group from this match" group)
+                        matchTy.AddMember(prop)
+
+                // Provide strongly typed version of Regex.Match instance method
+                let matchMeth = ProvidedMethod(
+                                    methodName = "Match", 
+                                    parameters = [ProvidedParameter("input", typeof<string>)], 
+                                    returnType = matchTy, 
+                                    InvokeCode = fun args -> <@@ ((%%args.[0]:obj) :?> Regex).Match(%%args.[1]) :> obj @@>)
+                matchMeth.AddXmlDoc "Searches the specified input string for the first occurence of this regular expression"
+            
+                ty.AddMember matchMeth
+            
+                // Declare a constructor
+                let ctor = ProvidedConstructor(
+                            parameters = [], 
+                            InvokeCode = fun args -> <@@ Regex(pattern) :> obj @@>)
+
+                // Add documentation to the constructor
+                ctor.AddXmlDoc "Initializes a regular expression instance"
+
+                ty.AddMember ctor
+            
+                ty
+              | _ -> failwith "unexpected parameter values")) 
+
+        do this.AddNamespace(rootNamespace, [regexTy])
+
+[<assembly:TypeProviderAssembly>]
+do()
diff --git a/vsintegration/src/unittests/Resources.MockTypeProviders/DummyProviderForLanguageServiceTesting/DummyProviderForLanguageServiceTesting.fsproj b/vsintegration/src/unittests/Resources.MockTypeProviders/DummyProviderForLanguageServiceTesting/DummyProviderForLanguageServiceTesting.fsproj
new file mode 100644
index 0000000..d2fdabb
--- /dev/null
+++ b/vsintegration/src/unittests/Resources.MockTypeProviders/DummyProviderForLanguageServiceTesting/DummyProviderForLanguageServiceTesting.fsproj
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information. -->
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <FSharpSourcesRoot>..\..\..\..\..\src</FSharpSourcesRoot>
+    <ProjectLanguage>FSharp</ProjectLanguage>
+  </PropertyGroup>
+  <Import Project="$(FSharpSourcesRoot)\FSharpSource.settings.targets" />
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{6AFF752D-E991-4A08-9ED2-5BF46B0E0F8B}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AssemblyName>DummyProviderForLanguageServiceTesting</AssemblyName>
+    <TargetType>LIBRARY</TargetType>
+    <NoWarn>58;75</NoWarn>
+    <GenerateDocumentationFile>false</GenerateDocumentationFile>
+    <EnsureThereAreNoUnusedFsSrGenResources>False</EnsureThereAreNoUnusedFsSrGenResources>
+    <DefineConstants>DEBUG;TRACE;$(DefineConstants)</DefineConstants>
+    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+    <CustomOutputPath>true</CustomOutputPath>
+    <OutputPath>$(FSharpSourcesRoot)\..\$(Configuration)\$(TargetFramework)\bin\UnitTestsResources\MockTypeProviders</OutputPath>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+    <Reference Include="mscorlib" />
+    <ProjectReference Include="$(FSharpSourcesRoot)\fsharp\FSharp.Core\FSharp.Core.fsproj">
+      <Project>{DED3BBD7-53F4-428A-8C9F-27968E768605}</Project>
+      <Name>FSharp.Core</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <ItemGroup>
+    <FsSrGen Include="$(FSharpSourcesRoot)\fsharp\FSharp.Data.TypeProviders\FSData.txt" >
+      <Link>FSData.txt</Link>
+    </FsSrGen>
+    <Compile Include="TypeProviderEmit.fsi" />
+    <Compile Include="TypeProviderEmit.fs" />
+    <Compile Include="DummyProviderForLanguageServiceTesting.fs" />
+  </ItemGroup>
+  <Import Project="$(FSharpSourcesRoot)\FSharpSource.targets" />
+</Project>
\ No newline at end of file
diff --git a/vsintegration/src/unittests/Resources.MockTypeProviders/DummyProviderForLanguageServiceTesting/TypeProviderEmit.fs b/vsintegration/src/unittests/Resources.MockTypeProviders/DummyProviderForLanguageServiceTesting/TypeProviderEmit.fs
new file mode 100644
index 0000000..82c5929
--- /dev/null
+++ b/vsintegration/src/unittests/Resources.MockTypeProviders/DummyProviderForLanguageServiceTesting/TypeProviderEmit.fs
@@ -0,0 +1,1495 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+#if TPEMIT_INTERNAL_AND_MINIMAL_FOR_TYPE_CONTAINERS
+namespace Internal.Utilities.TypeProvider.Emit
+#else
+namespace Microsoft.FSharp.TypeProvider.Emit
+#endif
+
+
+open System
+open System.Text
+open System.IO
+open System.Reflection
+open System.Reflection.Emit
+open System.Collections.Generic
+open Microsoft.FSharp.Core.CompilerServices
+
+[<AutoOpen>]
+module Misc =
+    let nonNull str x = if x=null then failwith ("Null in " + str) else x
+    let notRequired opname item = 
+        let msg = sprintf "The operation '%s' on item '%s' should not be called on provided type, member or parameter" opname item
+        System.Diagnostics.Debug.Assert (false, msg)
+        raise (System.NotSupportedException msg)
+
+    let mkEditorHideMethodsCustomAttributeData() = 
+        { new CustomAttributeData() with 
+                member __.Constructor =  typeof<TypeProviderEditorHideMethodsAttribute>.GetConstructors().[0]
+                member __.ConstructorArguments = upcast [| |]
+                member __.NamedArguments = upcast [| |] }
+
+    /// This makes an xml doc attribute w.r.t. an amortized computation of an xml doc string.
+    /// It is important that the text of the xml doc only get forced when poking on the ConstructorArguments
+    /// for the CustomAttributeData object.
+    let mkXmlDocCustomAttributeDataLazy(lazyText: Lazy<string>) = 
+        { new CustomAttributeData() with 
+                member __.Constructor =  typeof<TypeProviderXmlDocAttribute>.GetConstructors().[0]
+                member __.ConstructorArguments = upcast [| CustomAttributeTypedArgument(typeof<string>, lazyText.Force())  |]
+                member __.NamedArguments = upcast [| |] }
+
+    let mkXmlDocCustomAttributeData(s:string) =  mkXmlDocCustomAttributeDataLazy (lazy s)
+
+    let mkDefinitionLocationAttributeCustomAttributeData(line:int,column:int,filePath:string) = 
+        { new CustomAttributeData() with 
+                member __.Constructor =  typeof<TypeProviderDefinitionLocationAttribute>.GetConstructors().[0]
+                member __.ConstructorArguments = upcast [| |]
+                member __.NamedArguments = 
+                    upcast [| CustomAttributeNamedArgument(typeof<TypeProviderDefinitionLocationAttribute>.GetProperty("FilePath"), CustomAttributeTypedArgument(typeof<string>, filePath));
+                              CustomAttributeNamedArgument(typeof<TypeProviderDefinitionLocationAttribute>.GetProperty("Line"), CustomAttributeTypedArgument(typeof<int>, line)) ;
+                              CustomAttributeNamedArgument(typeof<TypeProviderDefinitionLocationAttribute>.GetProperty("Column"), CustomAttributeTypedArgument(typeof<int>, column)) 
+                           |] }
+
+    type CustomAttributesImpl() =
+        let customAttributes = ResizeArray<CustomAttributeData>()
+        let mutable hideObjectMethods = false
+        let mutable xmlDocDelayed = None
+        let mutable xmlDocAlwaysRecomputed = None
+
+        // XML doc text that we only compute once, if any. This must _not_ be forced until the ConstructorArguments
+        // property of the custom attribute is foced.
+        let xmlDocDelayedText = 
+            lazy 
+                (match xmlDocDelayed with None -> assert false; "" | Some f -> f())
+
+        // Custom atttributes that we only compute once
+        let customAttributesOnce = 
+            lazy 
+               [| if hideObjectMethods then yield mkEditorHideMethodsCustomAttributeData() 
+                  match xmlDocDelayed with None -> () | Some _ -> customAttributes.Add(mkXmlDocCustomAttributeDataLazy xmlDocDelayedText) 
+                  yield! customAttributes |]
+
+        member __.AddDefinitionLocation(line:int,column:int,filePath:string) = customAttributes.Add(mkDefinitionLocationAttributeCustomAttributeData(line, column, filePath))
+        member __.AddXmlDocComputed(xmlDoc : unit -> string) = xmlDocAlwaysRecomputed <- Some xmlDoc
+        member __.AddXmlDocDelayed(xmlDoc : unit -> string) = xmlDocDelayed <- Some xmlDoc
+        member this.AddXmlDoc(text:string) =  this.AddXmlDocDelayed (fun () -> text)
+        member __.HideObjectMethods with set v = hideObjectMethods <- v
+        member __.GetCustomAttributesData() = 
+            [| yield! customAttributesOnce.Force()
+               match xmlDocAlwaysRecomputed with None -> () | Some f -> customAttributes.Add(mkXmlDocCustomAttributeData (f()))  |]
+            :> IList<_>
+
+
+    let transQuotationToCode qexprf (argExprs: Quotations.Expr[]) = 
+        let expr = qexprf (Array.toList argExprs)
+        let rec trans q = 
+            match q with 
+            // Eliminate F# property gets to method calls
+            | Quotations.Patterns.PropertyGet(obj,propInfo,args) -> 
+                match obj with 
+                | None -> trans (Quotations.Expr.Call(propInfo.GetGetMethod(),args))
+                | Some o -> trans (Quotations.Expr.Call(trans o,propInfo.GetGetMethod(),args))
+            // Eliminate F# property sets to method calls
+            | Quotations.Patterns.PropertySet(obj,propInfo,args,v) -> 
+                 match obj with 
+                 | None -> trans (Quotations.Expr.Call(propInfo.GetSetMethod(),args@[v]))
+                 | Some o -> trans (Quotations.Expr.Call(trans o,propInfo.GetSetMethod(),args@[v]))
+            // Eliminate F# function applications to FSharpFunc<_,_>.Invoke calls
+            | Quotations.Patterns.Application(f,e) -> 
+                trans (Quotations.Expr.Call(trans f, f.Type.GetMethod "Invoke", [ e ]) )
+            | Quotations.Patterns.NewUnionCase(ci, es) ->
+                trans (Quotations.Expr.Call(Reflection.FSharpValue.PreComputeUnionConstructorInfo ci, es) )
+            | Quotations.Patterns.NewRecord(ci, es) ->
+                trans (Quotations.Expr.NewObject(Reflection.FSharpValue.PreComputeRecordConstructorInfo ci, es) )
+            | Quotations.Patterns.UnionCaseTest(e,uc) ->
+                let tagInfo = Reflection.FSharpValue.PreComputeUnionTagMemberInfo uc.DeclaringType
+                let tagExpr = 
+                    match tagInfo with 
+                    | :? PropertyInfo as tagProp ->
+                         trans (Quotations.Expr.PropertyGet(e,tagProp) )
+                    | :? MethodInfo as tagMeth -> 
+                         if tagMeth.IsStatic then trans (Quotations.Expr.Call(tagMeth, [e]))
+                         else trans (Quotations.Expr.Call(e,tagMeth,[]))
+                    | _ -> failwith "unreachable: unexpected result from PreComputeUnionTagMemberInfo"
+                let tagNumber = uc.Tag
+                trans <@@ (%%(tagExpr) : int) = tagNumber @@>
+
+            // Handle the generic cases
+            | Quotations.ExprShape.ShapeLambda(v,body) -> 
+                Quotations.Expr.Lambda(v, trans body)
+            | Quotations.ExprShape.ShapeCombination(comb,args) -> 
+                Quotations.ExprShape.RebuildShapeCombination(comb,List.map trans args)
+            | Quotations.ExprShape.ShapeVar _ -> q
+        trans expr
+
+    let adjustTypeAttributes attributes isNested = 
+        let visibilityAttributes = 
+            match attributes &&& TypeAttributes.VisibilityMask with 
+            | TypeAttributes.Public when isNested -> TypeAttributes.NestedPublic
+            | TypeAttributes.NotPublic when isNested -> TypeAttributes.NestedAssembly
+            | TypeAttributes.NestedPublic when not isNested -> TypeAttributes.Public
+            | TypeAttributes.NestedAssembly 
+            | TypeAttributes.NestedPrivate 
+            | TypeAttributes.NestedFamORAssem
+            | TypeAttributes.NestedFamily
+            | TypeAttributes.NestedFamANDAssem when not isNested -> TypeAttributes.NotPublic
+            | a -> a
+        (attributes &&& ~~~TypeAttributes.VisibilityMask) ||| visibilityAttributes
+
+type ProvidedStaticParameter(parameterName:string,parameterType:Type,?parameterDefaultValue:obj) = 
+    inherit System.Reflection.ParameterInfo()
+
+    override __.RawDefaultValue = defaultArg parameterDefaultValue null
+    override __.Attributes = if parameterDefaultValue.IsNone then enum 0 else ParameterAttributes.Optional
+    override __.Position = 0
+    override __.ParameterType = parameterType
+    override __.Name = parameterName 
+
+    override __.GetCustomAttributes(_inherit) = ignore(_inherit); notRequired "GetCustomAttributes" parameterName
+    override __.GetCustomAttributes(_attributeType, _inherit) = notRequired "GetCustomAttributes" parameterName
+
+type ProvidedParameter(name:string,parameterType:Type,?isOut:bool,?optionalValue:obj) = 
+    inherit System.Reflection.ParameterInfo()
+    let customAttributesImpl = CustomAttributesImpl()
+    let isOut = defaultArg isOut false
+    override this.Name = name
+    override this.ParameterType = parameterType
+    override this.Attributes = (base.Attributes ||| (if isOut then ParameterAttributes.Out else enum 0)
+                                                ||| (match optionalValue with None -> enum 0 | Some _ -> ParameterAttributes.Optional ||| ParameterAttributes.HasDefault))
+    override this.RawDefaultValue = defaultArg optionalValue null
+    override __.GetCustomAttributesData() = customAttributesImpl.GetCustomAttributesData()
+
+
+type ProvidedConstructor(parameters : ProvidedParameter list) = 
+    inherit ConstructorInfo()
+    let parameters  = parameters |> List.map (fun p -> p :> ParameterInfo) 
+
+    let mutable declaringType = null : System.Type
+    let mutable invokeCode    = None : option<Quotations.Expr[] -> Quotations.Expr>
+    let nameText () = sprintf "constructor for %s" (if declaringType=null then "<not yet known type>" else declaringType.FullName)
+
+    let customAttributesImpl = CustomAttributesImpl()
+    member this.AddXmlDocComputed xmlDoc                    = customAttributesImpl.AddXmlDocComputed xmlDoc
+    member this.AddXmlDocDelayed xmlDoc                     = customAttributesImpl.AddXmlDocDelayed xmlDoc
+    member this.AddXmlDoc xmlDoc                            = customAttributesImpl.AddXmlDoc xmlDoc
+    member this.AddDefinitionLocation(line,column,filePath) = customAttributesImpl.AddDefinitionLocation(line, column, filePath)
+    member this.HideObjectMethods with set v                = customAttributesImpl.HideObjectMethods <- v
+    override this.GetCustomAttributesData()                 = customAttributesImpl.GetCustomAttributesData()
+
+    member this.DeclaringTypeImpl 
+        with set x = 
+            if declaringType<>null then failwith (sprintf "ProvidedConstructor: declaringType already set on '%s'" (nameText())); 
+            declaringType <- x
+
+    member this.InvokeCode 
+        with set (q:Quotations.Expr list -> Quotations.Expr) = this.InvokeCodeInternal <- transQuotationToCode q
+
+    member this.InvokeCodeInternal 
+        with get() = 
+            match invokeCode with
+            | Some f -> f
+            | None -> failwith (sprintf "ProvidedConstructor: no invoker for '%s'" (nameText()))
+        and  set f = 
+            match invokeCode with
+            | None -> invokeCode <- Some f
+            | Some _ -> failwith (sprintf "ProvidedConstructor: code already given for '%s'" (nameText()))
+
+    // Implement overloads
+    override this.GetParameters() = parameters |> List.toArray 
+    override this.Attributes = MethodAttributes.Public ||| MethodAttributes.RTSpecialName
+    override this.Name = if this.IsStatic then ".cctor" else ".ctor"
+    override this.DeclaringType = declaringType |> nonNull "ProvidedConstructor.DeclaringType"                                   
+    override this.IsDefined(_attributeType, _inherit) = true 
+
+    override this.Invoke(_invokeAttr, _binder, _parameters, _culture)      = notRequired "Invoke" (nameText())
+    override this.Invoke(_obj, _invokeAttr, _binder, _parameters, _culture) = notRequired "Invoke" (nameText())
+    override this.ReflectedType                                        = notRequired "ReflectedType" (nameText())
+    override this.GetMethodImplementationFlags()                       = notRequired "GetMethodImplementationFlags" (nameText())
+    override this.MethodHandle                                         = notRequired "MethodHandle" (nameText())
+    override this.GetCustomAttributes(_inherit)                     = notRequired "GetCustomAttributes" (nameText())
+    override this.GetCustomAttributes(_attributeType, _inherit)      = notRequired "GetCustomAttributes" (nameText())
+
+type ProvidedMethod(methodName: string, parameters: ProvidedParameter list, returnType: Type) =
+    inherit System.Reflection.MethodInfo()
+    let argParams = parameters |> List.map (fun p -> p :> ParameterInfo) 
+
+    // State
+    let mutable declaringType : Type = null
+    let mutable methodAttrs   = MethodAttributes.Public
+    let mutable invokeCode    = None : option<Quotations.Expr[] -> Quotations.Expr>
+
+    let customAttributesImpl = CustomAttributesImpl()
+    member this.AddXmlDocComputed xmlDoc                    = customAttributesImpl.AddXmlDocComputed xmlDoc
+    member this.AddXmlDocDelayed xmlDoc                     = customAttributesImpl.AddXmlDocDelayed xmlDoc
+    member this.AddXmlDoc xmlDoc                            = customAttributesImpl.AddXmlDoc xmlDoc
+    member this.AddDefinitionLocation(line,column,filePath) = customAttributesImpl.AddDefinitionLocation(line, column, filePath)
+    override this.GetCustomAttributesData()                 = customAttributesImpl.GetCustomAttributesData()
+
+    member this.SetMethodAttrs m = methodAttrs <- m 
+    member this.AddMethodAttrs m = methodAttrs <- methodAttrs ||| m
+    member this.DeclaringTypeImpl with set x = declaringType <- x // check: not set twice
+    member this.IsStaticMethod 
+        with get()  = methodAttrs.HasFlag(MethodAttributes.Static)
+        and set x = if x then methodAttrs <- methodAttrs ||| MethodAttributes.Static
+                    else methodAttrs <- methodAttrs &&& (~~~ MethodAttributes.Static)
+    member this.InvokeCode 
+        with set  (q:Quotations.Expr list -> Quotations.Expr) = this.InvokeCodeInternal <- transQuotationToCode q
+
+    member this.InvokeCodeInternal 
+        with get() = 
+            match invokeCode with
+            | Some f -> f
+            | None -> failwith (sprintf "ProvidedMethod: no invoker for %s on type %s" this.Name (if declaringType=null then "<not yet known type>" else declaringType.FullName))
+        and  set f = 
+            match invokeCode with
+            | None -> invokeCode <- Some f
+            | Some _ -> failwith (sprintf "ProvidedConstructor: code already given for %s on type %s" this.Name (if declaringType=null then "<not yet known type>" else declaringType.FullName))
+
+    // Implement overloads
+    override this.GetParameters() = argParams |> Array.ofList
+    override this.Attributes = methodAttrs
+    override this.Name = methodName
+    override this.DeclaringType = declaringType |> nonNull "ProvidedMethod.DeclaringType"                                   
+    override this.IsDefined(_attributeType, _inherit) : bool = true
+    override this.MemberType = MemberTypes.Method
+    override this.CallingConvention = 
+        let cc = CallingConventions.Standard
+        let cc = if not (this.IsStatic) then cc ||| CallingConventions.HasThis else cc
+        cc
+    override this.ReturnType = returnType
+    override this.ReturnParameter = null // REVIEW: Give it a name and type?
+    override this.ToString() = "Method " + this.Name
+
+    override this.ReturnTypeCustomAttributes                           = notRequired "ReturnTypeCustomAttributes" this.Name
+    override this.GetBaseDefinition()                                  = notRequired "GetBaseDefinition" this.Name
+    override this.GetMethodImplementationFlags()                       = notRequired "GetMethodImplementationFlags" this.Name
+    override this.MethodHandle                                         = notRequired "MethodHandle" this.Name
+    override this.Invoke(_obj, _invokeAttr, _binder, _parameters, _culture) = notRequired "Invoke" this.Name
+    override this.ReflectedType                                        = notRequired "ReflectedType" this.Name
+    override this.GetCustomAttributes(_inherit)                     = notRequired "GetCustomAttributes" this.Name
+    override this.GetCustomAttributes(_attributeType, _inherit)      =  notRequired "GetCustomAttributes" this.Name
+
+
+type ProvidedProperty(propertyName:string,propertyType:Type, ?parameters:ProvidedParameter list) = 
+    inherit System.Reflection.PropertyInfo()
+    // State
+
+    let parameters = defaultArg parameters []
+    let mutable declaringType = null
+    let mutable isStatic = false
+    let mutable getterCode = None : option<Quotations.Expr[] -> Quotations.Expr>
+    let mutable setterCode = None : option<Quotations.Expr[] -> Quotations.Expr>
+
+    let hasGetter() = getterCode.IsSome
+    let hasSetter() = setterCode.IsSome
+
+    // Delay construction - to pick up the latest isStatic
+    let markSpecialName (m:ProvidedMethod) = m.AddMethodAttrs(MethodAttributes.SpecialName); m
+    let getter = lazy (ProvidedMethod("get_" + propertyName,parameters,propertyType,IsStaticMethod=isStatic,DeclaringTypeImpl=declaringType,InvokeCodeInternal=getterCode.Value) |> markSpecialName)  
+    let setter = lazy (ProvidedMethod("set_" + propertyName,parameters @ [ProvidedParameter("value",propertyType)],typeof<System.Void>,IsStaticMethod=isStatic,DeclaringTypeImpl=declaringType,InvokeCodeInternal=setterCode.Value) |> markSpecialName) 
+ 
+    let customAttributesImpl = CustomAttributesImpl()
+    member this.AddXmlDocComputed xmlDoc                    = customAttributesImpl.AddXmlDocComputed xmlDoc
+    member this.AddXmlDocDelayed xmlDoc                     = customAttributesImpl.AddXmlDocDelayed xmlDoc
+    member this.AddXmlDoc xmlDoc                            = customAttributesImpl.AddXmlDoc xmlDoc
+    member this.AddDefinitionLocation(line,column,filePath) = customAttributesImpl.AddDefinitionLocation(line, column, filePath)
+    override this.GetCustomAttributesData()                 = customAttributesImpl.GetCustomAttributesData()
+
+    member this.DeclaringTypeImpl with set x = declaringType <- x // check: not set twice
+    member this.IsStatic 
+        with get()  = isStatic
+        and set x = isStatic <- x
+
+    member this.GetterCode 
+        with set  (q:Quotations.Expr list -> Quotations.Expr) = this.GetterCodeInternal <- transQuotationToCode q
+
+    member this.GetterCodeInternal 
+        with get() = getterCode.Value
+        and  set f = 
+            if not getter.IsValueCreated then getterCode <- Some f else failwith "ProvidedProperty: getter MethodInfo has already been created"                                         
+
+    member this.SetterCode 
+        with set (q:Quotations.Expr list -> Quotations.Expr) = this.SetterCodeInternal <- transQuotationToCode q
+
+    member this.SetterCodeInternal 
+        with get() = setterCode.Value
+        and  set f = 
+            if not (setter.IsValueCreated) then setterCode <- Some f else failwith "ProvidedProperty: setter MethodInfo has already been created"
+
+    // Implement overloads
+    override this.PropertyType = propertyType
+    override this.SetValue(_obj, _value, _invokeAttr, _binder, _index, _culture) = notRequired "SetValue" this.Name
+    override this.GetAccessors _nonPublic  = notRequired "nonPublic" this.Name
+    override this.GetGetMethod _nonPublic = if hasGetter() then getter.Force() :> MethodInfo else null
+    override this.GetSetMethod _nonPublic = if hasSetter() then setter.Force() :> MethodInfo else null
+    override this.GetIndexParameters() = [| for p in parameters -> upcast p |]
+    override this.Attributes = PropertyAttributes.None
+    override this.CanRead = hasGetter()
+    override this.CanWrite = hasSetter()
+    override this.GetValue(_obj, _invokeAttr, _binder, _index, _culture) : obj = notRequired "GetValue" this.Name
+    override this.Name = propertyName
+    override this.DeclaringType = declaringType |> nonNull "ProvidedProperty.DeclaringType"
+    override this.MemberType : MemberTypes = MemberTypes.Property
+
+    override this.ReflectedType                                     = notRequired "ReflectedType" this.Name
+    override this.GetCustomAttributes(_inherit)                  = notRequired "GetCustomAttributes" this.Name
+    override this.GetCustomAttributes(_attributeType, _inherit)   = notRequired "GetCustomAttributes" this.Name
+    override this.IsDefined(_attributeType, _inherit)             = notRequired "IsDefined" this.Name
+
+type ProvidedLiteralField(fieldName:string,fieldType:Type,literalValue:obj) = 
+    inherit System.Reflection.FieldInfo()
+    // State
+
+    let mutable declaringType = null
+
+    let customAttributesImpl = CustomAttributesImpl()
+    member this.AddXmlDocComputed xmlDoc                    = customAttributesImpl.AddXmlDocComputed xmlDoc
+    member this.AddXmlDocDelayed xmlDoc                     = customAttributesImpl.AddXmlDocDelayed xmlDoc
+    member this.AddXmlDoc xmlDoc                            = customAttributesImpl.AddXmlDoc xmlDoc
+    member this.AddDefinitionLocation(line,column,filePath) = customAttributesImpl.AddDefinitionLocation(line, column, filePath)
+    override this.GetCustomAttributesData()                 = customAttributesImpl.GetCustomAttributesData()
+
+    member this.DeclaringTypeImpl with set x = declaringType <- x // check: not set twice
+
+
+    // Implement overloads
+    override this.FieldType = fieldType
+    override this.GetRawConstantValue()  = literalValue
+    override this.Attributes = FieldAttributes.Static ||| FieldAttributes.Literal ||| FieldAttributes.Public
+    override this.Name = fieldName
+    override this.DeclaringType = declaringType |> nonNull "ProvidedLiteralField.DeclaringType"
+    override this.MemberType : MemberTypes = MemberTypes.Field
+
+    override this.ReflectedType                                     = notRequired "ReflectedType" this.Name
+    override this.GetCustomAttributes(_inherit)                  = notRequired "GetCustomAttributes" this.Name
+    override this.GetCustomAttributes(_attributeType, _inherit)   = notRequired "GetCustomAttributes" this.Name
+    override this.IsDefined(_attributeType, _inherit)             = notRequired "IsDefined" this.Name
+
+    override this.SetValue(_obj, _value, _invokeAttr, _binder, _culture) = notRequired "SetValue" this.Name
+    override this.GetValue(_obj) : obj = notRequired "GetValue" this.Name
+    override this.FieldHandle = notRequired "FieldHandle" this.Name
+
+/// Represents the type constructor in a provided symbol type.
+type SymbolKind = 
+    | SDArray 
+    | Array of int 
+    | Pointer 
+    | ByRef 
+    | Generic of System.Type
+    | FSharpTypeAbbreviation of (System.Reflection.Assembly * string * string)
+
+
+/// Represents an array or other symbolic type involving a provided type as the argument.
+/// See the type provider spec for the methods that must be implemented.
+/// Note that the type provider specification does not require us to implement pointer-equality for provided types.
+type ProvidedSymbolType(kind: SymbolKind, args: Type list) =
+    inherit Type()
+
+    override this.FullName =   
+        match kind,args with 
+        | SymbolKind.SDArray,[arg] -> arg.FullName + "[]" 
+        | SymbolKind.Array _,[arg] -> arg.FullName + "[*]" 
+        | SymbolKind.Pointer,[arg] -> arg.FullName + "*" 
+        | SymbolKind.ByRef,[arg] -> arg.FullName + "&"
+        | SymbolKind.Generic gty, args -> gty.FullName + args.ToString()
+        | SymbolKind.FSharpTypeAbbreviation (_,nsp,path),args -> nsp + "." + path + args.ToString()
+        | _ -> failwith "unreachable"
+   
+    /// Although not strictly required by the type provider specification, this is required when doing basic operations like FullName on
+    /// .NET symbolic types made from this type, e.g. when building Nullable<SomeProvidedType[]>.FullName
+    override this.DeclaringType =                                                                 
+        match kind,args with 
+        | SymbolKind.SDArray,[arg] -> arg
+        | SymbolKind.Array _,[arg] -> arg
+        | SymbolKind.Pointer,[arg] -> arg
+        | SymbolKind.ByRef,[arg] -> arg
+        | SymbolKind.Generic gty,_ -> gty
+        | SymbolKind.FSharpTypeAbbreviation _,_ -> null
+        | _ -> failwith "unreachable"
+
+    override this.Name =
+        match kind,args with 
+        | SymbolKind.SDArray,[arg] -> arg.Name + "[]" 
+        | SymbolKind.Array _,[arg] -> arg.Name + "[*]" 
+        | SymbolKind.Pointer,[arg] -> arg.Name + "*" 
+        | SymbolKind.ByRef,[arg] -> arg.Name + "&"
+        | SymbolKind.Generic gty, args -> gty.FullName + args.ToString()
+        | SymbolKind.FSharpTypeAbbreviation (_,_,path),_ -> path
+        | _ -> failwith "unreachable"
+
+    override this.BaseType =
+        match kind with 
+        | SymbolKind.SDArray -> typeof<System.Array>
+        | SymbolKind.Array _ -> typeof<System.Array>
+        | SymbolKind.Pointer -> typeof<System.ValueType>
+        | SymbolKind.ByRef -> typeof<System.ValueType>
+        | SymbolKind.Generic gty  -> gty.BaseType
+        | SymbolKind.FSharpTypeAbbreviation _ -> typeof<obj>
+
+    override this.GetArrayRank() = (match kind with SymbolKind.Array n -> n | SymbolKind.SDArray -> 1 | _ -> invalidOp "non-array type")
+    override this.IsArrayImpl() = (match kind with SymbolKind.Array _ | SymbolKind.SDArray -> true | _ -> false)
+    override this.IsByRefImpl() = (match kind with SymbolKind.ByRef _ -> true | _ -> false)
+    override this.IsPointerImpl() = (match kind with SymbolKind.Pointer _ -> true | _ -> false)
+    override this.IsPrimitiveImpl() = false
+    override this.IsGenericType = (match kind with SymbolKind.Generic _ -> true | _ -> false)
+    override this.GetGenericArguments() = (match kind with SymbolKind.Generic _ -> args |> List.toArray | _ -> invalidOp "non-generic type")
+    override this.GetGenericTypeDefinition() = (match kind with SymbolKind.Generic e -> e | _ -> invalidOp "non-generic type")
+    override this.IsCOMObjectImpl() = false
+    override this.HasElementTypeImpl() = (match kind with SymbolKind.Generic _ -> false | _ -> true)
+    override this.GetElementType() = (match kind,args with (SymbolKind.Array _  | SymbolKind.SDArray | SymbolKind.ByRef | SymbolKind.Pointer),[e] -> e | _ -> invalidOp "not an array, pointer or byref type")
+    override this.ToString() = this.FullName
+
+    override this.Module : Module                                                                  = notRequired "Module" this.Name
+    override this.Assembly = 
+        match kind with 
+        | SymbolKind.FSharpTypeAbbreviation (assembly,_nsp,_path) -> assembly
+        | _ -> notRequired "Assembly" this.Name
+    override this.Namespace = 
+        match kind with 
+        | SymbolKind.FSharpTypeAbbreviation (_assembly,nsp,_path) -> nsp
+        | _ -> notRequired "Namespace" this.Name
+    override this.GetConstructors _bindingAttr                                                      = notRequired "GetConstructors" this.Name
+    override this.GetMethodImpl(_name, _bindingAttr, _binderBinder, _callConvention, _types, _modifiers) = notRequired "GetMethodImpl" this.Name
+    override this.GetMembers _bindingAttr                                                           = notRequired "GetMembers" this.Name
+    override this.GetMethods _bindingAttr                                                           = notRequired "GetMethods" this.Name
+    override this.GetField(_name, _bindingAttr)                                                      = notRequired "GetField" this.Name
+    override this.GetFields _bindingAttr                                                            = notRequired "GetFields" this.Name
+    override this.GetInterface(_name, _ignoreCase)                                                   = notRequired "GetInterface" this.Name
+    override this.GetInterfaces()                                                                  = notRequired "GetInterfaces" this.Name
+    override this.GetEvent(_name, _bindingAttr)                                                      = notRequired "GetEvent" this.Name
+    override this.GetEvents _bindingAttr                                                            = notRequired "GetEvents" this.Name
+    override this.GetProperties _bindingAttr                                                        = notRequired "GetProperties" this.Name
+    override this.GetPropertyImpl(_name, _bindingAttr, _binder, _returnType, _types, _modifiers)         = notRequired "GetPropertyImpl" this.Name
+    override this.GetNestedTypes _bindingAttr                                                       = notRequired "GetNestedTypes" this.Name
+    override this.GetNestedType(_name, _bindingAttr)                                                 = notRequired "GetNestedType" this.Name
+    override this.GetAttributeFlagsImpl()                                                          = notRequired "GetAttributeFlagsImpl" this.Name
+    override this.UnderlyingSystemType                                                             = notRequired "UnderlyingSystemType" this.Name
+    override this.GetCustomAttributesData()                                                        = notRequired "GetCustomAttributesData" this.Name
+    override this.MemberType                                                                       = notRequired "MemberType" this.Name
+    override this.GetHashCode()                                                                    = notRequired "GetHashCode" this.Name
+    override this.Equals(_that:obj) : bool                                                          = notRequired "Equals" this.Name
+    override this.GetMember(_name,_mt,_bindingAttr)                                                   = notRequired "GetMember" this.Name
+    override this.GUID                                                                             = notRequired "GUID" this.Name
+    override this.InvokeMember(_name, _invokeAttr, _binder, _target, _args, _modifiers, _culture, _namedParameters) = notRequired "InvokeMember" this.Name
+    override this.AssemblyQualifiedName                                                            = notRequired "AssemblyQualifiedName" this.Name
+    override this.GetConstructorImpl(_bindingAttr, _binder, _callConvention, _types, _modifiers)        = notRequired "GetConstructorImpl" this.Name
+    override this.GetCustomAttributes(_inherit)                                                 = notRequired "GetCustomAttributes" this.Name
+    override this.GetCustomAttributes(_attributeType, _inherit)                                  = notRequired "GetCustomAttributes" this.Name
+    override this.IsDefined(_attributeType, _inherit)                                            = notRequired "IsDefined" this.Name
+
+
+
+[<Class>]
+type ProvidedMeasureBuilder() =
+
+    static let theBuilder = ProvidedMeasureBuilder()
+    static member Default = theBuilder
+    member b.One = typeof<Core.CompilerServices.MeasureOne> 
+    member b.Product (m1,m2) = typedefof<Core.CompilerServices.MeasureProduct<_,_>>.MakeGenericType [| m1;m2 |] 
+    member b.Inverse m = typedefof<Core.CompilerServices.MeasureInverse<_>>.MakeGenericType [| m |] 
+    member b.Ratio (m1, m2) = b.Product(m1, b.Inverse m2)
+    member b.Square m = b.Product(m, m)
+    member b.SI m = 
+        match typedefof<list<int>>.Assembly.GetType("Microsoft.FSharp.Data.UnitSystems.SI.UnitNames."+m) with 
+        | null ->         
+            ProvidedSymbolType
+               (SymbolKind.FSharpTypeAbbreviation
+                   (typeof<Core.CompilerServices.MeasureOne>.Assembly,
+                    "Microsoft.FSharp.Data.UnitSystems.SI.UnitNames", 
+                    m), 
+                []) :> Type
+        | v -> v
+    member b.AnnotateType (basicType, annotation) = ProvidedSymbolType(Generic basicType, annotation) :> Type
+
+
+[<RequireQualifiedAccess>]
+type TypeContainer =
+  | Namespace of Assembly * string // namespace
+  | Type of System.Type
+  | TypeToBeDecided
+
+module GlobalProvidedAssemblyElementsTable = 
+    let theTable = Dictionary<Assembly, byte[]>()
+
+type ProvidedTypeDefinition(container:TypeContainer,className : string, baseType  : Type option) as this =
+    inherit Type()
+    // state
+    let mutable attributes   = 
+        TypeAttributes.Public ||| 
+        TypeAttributes.Class ||| 
+        TypeAttributes.Sealed |||
+        enum (int32 TypeProviderTypeAttributes.IsErased)
+
+
+    let mutable baseType   = baseType
+    let mutable membersKnown   = ResizeArray<MemberInfo>()
+    let mutable membersQueue   = ResizeArray<(unit -> list<MemberInfo>)>()       
+    let mutable staticParams = [ ] 
+    let mutable staticParamsApply = None
+    let mutable container = container
+    let mutable interfaceImpls = ResizeArray<Type>()
+    let mutable methodOverrides = ResizeArray<ProvidedMethod * MethodInfo>()
+
+    // members API
+    let getMembers() = 
+        if membersQueue.Count > 0 then 
+            let elems = membersQueue |> Seq.toArray // take a copy in case more elements get added
+            membersQueue.Clear()
+            for  f in elems do
+                for i in f() do 
+                    membersKnown.Add i       
+                    match i with
+                    | :? ProvidedProperty    as p -> 
+                        if p.CanRead then membersKnown.Add (p.GetGetMethod true)
+                        if p.CanWrite then membersKnown.Add (p.GetSetMethod true)
+                    | _ -> ()
+        
+        membersKnown.ToArray()
+
+    let mutable theAssembly = 
+      lazy
+        match container with
+        | TypeContainer.Namespace (theAssembly, rootNamespace) ->
+            if theAssembly = null then failwith "Null assemblies not allowed"
+            if rootNamespace<>null && rootNamespace.Length=0 then failwith "Use 'null' for global namespace"
+            theAssembly
+        | TypeContainer.Type superTy -> superTy.Assembly
+        | TypeContainer.TypeToBeDecided -> failwith (sprintf "type '%s' was not added as a member to a declaring type" this.Name)
+    
+    let rootNamespace =
+      lazy 
+        match container with
+        | TypeContainer.Namespace (_,rootNamespace) -> rootNamespace
+        | TypeContainer.Type enclosingTyp           -> enclosingTyp.Namespace
+        | TypeContainer.TypeToBeDecided -> failwith (sprintf "type '%s' was not added as a member to a declaring type" this.Name)
+
+    let declaringType =
+      lazy
+        match container with
+        | TypeContainer.Namespace _ -> null
+        | TypeContainer.Type enclosingTyp           -> enclosingTyp
+        | TypeContainer.TypeToBeDecided -> failwith (sprintf "type '%s' was not added as a member to a declaring type" this.Name)
+
+    let fullName = 
+      lazy
+        match container with
+        | TypeContainer.Type declaringType -> declaringType.FullName + "+" + className
+        | TypeContainer.Namespace (_,namespaceName) ->  
+            if namespaceName="" then failwith "use null for global namespace"
+            match namespaceName with
+            | null -> className
+            | _    -> namespaceName + "." + className
+        | TypeContainer.TypeToBeDecided -> failwith (sprintf "type '%s' was not added as a member to a declaring type" this.Name)
+                                                            
+    let patchUpAddedMemberInfo (this:Type) (m:MemberInfo) = 
+        match m with
+        | :? ProvidedConstructor as c -> c.DeclaringTypeImpl <- this // patch up "declaring type" on provided MethodInfo
+        | :? ProvidedMethod      as m -> m.DeclaringTypeImpl <- this // patch up "declaring type" on provided MethodInfo
+        | :? ProvidedProperty    as p -> p.DeclaringTypeImpl <- this // patch up "declaring type" on provided MethodInfo
+        | :? ProvidedTypeDefinition  as t -> t.DeclaringTypeImpl <- this 
+        | :? ProvidedLiteralField as l -> l.DeclaringTypeImpl <- this
+        | _ -> ()
+
+    let customAttributesImpl = CustomAttributesImpl()
+    member this.AddXmlDocComputed xmlDoc                    = customAttributesImpl.AddXmlDocComputed xmlDoc
+    member this.AddXmlDocDelayed xmlDoc                     = customAttributesImpl.AddXmlDocDelayed xmlDoc
+    member this.AddXmlDoc xmlDoc                            = customAttributesImpl.AddXmlDoc xmlDoc
+    member this.AddDefinitionLocation(line,column,filePath) = customAttributesImpl.AddDefinitionLocation(line, column, filePath)
+    member this.HideObjectMethods with set v                = customAttributesImpl.HideObjectMethods <- v
+    override this.GetCustomAttributesData()                 = customAttributesImpl.GetCustomAttributesData()
+
+    new (assembly:Assembly,namespaceName,className,baseType) = new ProvidedTypeDefinition(TypeContainer.Namespace (assembly,namespaceName), className, baseType)
+    new (className,baseType) = new ProvidedTypeDefinition(TypeContainer.TypeToBeDecided, className, baseType)
+    // state ops
+
+    member this.SetBaseType t = baseType <- Some t
+    member this.SetAttributes x = attributes <- x
+    // Add MemberInfos
+    member this.AddMembersDelayed(makeMS : unit -> list<#MemberInfo>) =
+        membersQueue.Add (fun () -> makeMS() |> List.map (fun x -> patchUpAddedMemberInfo this x; x :> MemberInfo ))
+    member this.AddMembers(ms:list<#MemberInfo>) = (* strict *)
+        ms |> List.iter (patchUpAddedMemberInfo this) // strict: patch up now
+        membersQueue.Add (fun () -> ms |> List.map (fun x -> x :> MemberInfo))
+    member this.AddMember(m:MemberInfo) = this.AddMembers [m]    
+    member this.AddMemberDelayed(m : unit -> #MemberInfo) = this.AddMembersDelayed(fun () -> [m()])
+
+    member this.AddAssemblyTypesAsNestedTypesDelayed (assemblyf : unit -> System.Reflection.Assembly)  = 
+            let bucketByPath nodef tipf (items: (string list * 'Value) list) = 
+                // Find all the items with an empty key list and call 'tipf' 
+                let tips = 
+                    [ for (keylist,v) in items do 
+                         match keylist with 
+                         | [] -> yield tipf v
+                         | _ -> () ]
+
+                // Find all the items with a non-empty key list. Bucket them together by
+                // the first key. For each bucket, call 'nodef' on that head key and the bucket.
+                let nodes = 
+                    let buckets = new Dictionary<_,_>(10)
+                    for (keylist,v) in items do
+                        match keylist with 
+                        | [] -> ()
+                        | key::rest -> 
+                            buckets.[key] <- (rest,v) :: (if buckets.ContainsKey key then buckets.[key] else []);
+
+                    [ for (KeyValue(key,items)) in buckets -> nodef key items ]
+
+                tips @ nodes
+            this.AddMembersDelayed (fun _ -> 
+                let topTypes = [ for ty in assemblyf().GetTypes() do 
+                                        if not ty.IsNested then
+                                             let namespaceParts = match ty.Namespace with null -> [] | s -> s.Split '.' |> Array.toList
+                                             yield namespaceParts,  ty ]
+                let rec loop types = 
+                    types 
+                    |> bucketByPath
+                        (fun namespaceComponent typesUnderNamespaceComponent -> 
+                            let t = ProvidedTypeDefinition(namespaceComponent, baseType = Some typeof<obj>)
+                            t.AddMembers (loop typesUnderNamespaceComponent)
+                            (t :> Type))
+                        (fun ty -> ty)
+                loop topTypes)
+
+    /// Abstract a type to a parametric-type. Requires "formal parameters" and "instantiation function".
+    member this.DefineStaticParameters(staticParameters : list<ProvidedStaticParameter>, apply    : (string -> obj[] -> ProvidedTypeDefinition)) =
+        staticParams      <- staticParameters 
+        staticParamsApply <- Some apply
+
+    /// Get ParameterInfo[] for the parametric type parameters (//s GetGenericParameters)
+    member this.GetStaticParameters() = [| for p in staticParams -> p :> ParameterInfo |]
+
+    /// Instantiate parametrics type
+    member this.MakeParametricType(name:string,args:obj[]) =
+        if staticParams.Length>0 then
+            if staticParams.Length <> args.Length then
+                failwith (sprintf "ProvidedTypeDefinition: expecting %d static parameters but given %d for type %s" staticParams.Length args.Length (fullName.Force()))
+            match staticParamsApply with
+            | None -> failwith "ProvidedTypeDefinition: DefineStaticParameters was not called"
+            | Some f -> f name args
+
+        else
+            failwith (sprintf "ProvidedTypeDefinition: static parameters supplied but not expected for %s" (fullName.Force()))
+
+    member this.DeclaringTypeImpl
+        with set x = 
+            match container with TypeContainer.TypeToBeDecided -> () | _ -> failwith (sprintf "container type for '%s' was already set to '%s'" this.FullName x.FullName); 
+            container <- TypeContainer.Type  x
+
+    // Implement overloads
+    override this.Assembly = theAssembly.Force()
+    member this.SetAssembly assembly = theAssembly <- lazy assembly
+    override this.FullName = fullName.Force()
+    override this.Namespace = rootNamespace.Force()
+    override this.BaseType = match baseType with Some ty -> ty | None -> null
+    // Constructors
+    override this.GetConstructors bindingAttr = 
+        [| for m in this.GetMembers bindingAttr do                
+                if m.MemberType = MemberTypes.Constructor then
+                    yield (m :?> ConstructorInfo) |]
+    // Methods
+    override this.GetMethodImpl(name, _bindingAttr, _binderBinder, _callConvention, _types, _modifiers) : MethodInfo = 
+        let membersWithName = 
+            [ for m in getMembers() do                
+                if m.MemberType.HasFlag(MemberTypes.Method) && m.Name = name then
+                    yield  m ]
+        match membersWithName with 
+        | []        -> null
+        | [meth]    -> meth :?> MethodInfo
+        | _several   -> failwith "GetMethodImpl. not support overloads"
+
+    override this.GetMethods bindingAttr = 
+        this.GetMembers bindingAttr 
+        |> Array.filter (fun m -> m.MemberType.HasFlag(MemberTypes.Method)) 
+        |> Array.map (fun m -> m :?> MethodInfo)
+
+    // Fields
+    override this.GetField(name, bindingAttr) = 
+        let fields = [| for m in this.GetMembers bindingAttr do
+                            if m.MemberType.HasFlag(MemberTypes.Field) && (name = null || m.Name = name) then // REVIEW: name = null. Is that a valid query?!
+                                yield m |] 
+        if fields.Length > 0 then fields.[0] :?> FieldInfo else null
+
+    override this.GetFields bindingAttr = 
+        [| for m in this.GetMembers bindingAttr do if m.MemberType.HasFlag(MemberTypes.Field) then yield m :?> FieldInfo |]
+
+    override this.GetInterface(_name, _ignoreCase) = notRequired "GetInterface" this.Name
+
+    override this.GetInterfaces() = 
+        [| yield! interfaceImpls  |]
+
+    member this.GetInterfaceImplementations() = 
+        [| yield! interfaceImpls |]
+
+    member this.AddInterfaceImplementation ityp = interfaceImpls.Add ityp
+    member this.GetMethodOverrides() = 
+        [| yield! methodOverrides |]
+    member this.DefineMethodOverride (bodyMethInfo,declMethInfo) = methodOverrides.Add (bodyMethInfo, declMethInfo)
+
+    // Events
+    override this.GetEvent(name, bindingAttr) = 
+        let events = this.GetMembers bindingAttr 
+                     |> Array.filter(fun m -> m.MemberType.HasFlag(MemberTypes.Event) && (name = null || m.Name = name)) 
+        if events.Length > 0 then events.[0] :?> EventInfo else null
+
+    override this.GetEvents bindingAttr = 
+        [| for m in this.GetMembers bindingAttr do if m.MemberType.HasFlag(MemberTypes.Event) then yield downcast m |]    
+
+    // Properties
+    override this.GetProperties bindingAttr = 
+        [| for m in this.GetMembers bindingAttr do if m.MemberType.HasFlag(MemberTypes.Property) then yield downcast m |]
+
+    override this.GetPropertyImpl(name, bindingAttr, binder, returnType, types, modifiers) = 
+        if returnType <> null then failwith "Need to handle specified return type in GetPropertyImpl"
+        if types      <> null then failwith "Need to handle specified parameter types in GetPropertyImpl"
+        if modifiers  <> null then failwith "Need to handle specified modifiers in GetPropertyImpl"
+        if binder  <> null then failwith "Need to handle binder in GetPropertyImpl"
+        let props = this.GetMembers bindingAttr |> Array.filter(fun m -> m.MemberType.HasFlag(MemberTypes.Property) && (name = null || m.Name = name))  // Review: nam = null, valid query!?
+        if props.Length > 0 then
+            props.[0] :?> PropertyInfo
+        else
+            null
+    // Nested Types
+    override this.MakeArrayType() = ProvidedSymbolType(SymbolKind.SDArray, [this]) :> Type
+    override this.MakeArrayType arg = ProvidedSymbolType(SymbolKind.Array arg, [this]) :> Type
+    override this.MakePointerType() = ProvidedSymbolType(SymbolKind.Pointer, [this]) :> Type
+    override this.MakeByRefType() = ProvidedSymbolType(SymbolKind.ByRef, [this]) :> Type
+
+    override this.GetMembers _bindingAttr = getMembers() 
+
+    override this.GetNestedTypes bindingAttr = 
+        this.GetMembers bindingAttr 
+        |> Array.filter(fun m -> 
+            m.MemberType.HasFlag(MemberTypes.NestedType) || 
+            // Allow 'fake' nested types that are actually real .NET types
+            m.MemberType.HasFlag(MemberTypes.TypeInfo)) |> Array.map(fun m -> m :?> Type)
+
+    override this.GetMember(name,mt,_bindingAttr) = 
+        let mt = 
+            if mt &&& MemberTypes.NestedType = MemberTypes.NestedType then 
+                mt ||| MemberTypes.TypeInfo 
+            else
+                mt
+        getMembers() |> Array.filter(fun m->0<>(int(m.MemberType &&& mt)) && m.Name = name)
+        
+    override this.GetNestedType(name, bindingAttr) = 
+        let nt = this.GetMember(name, MemberTypes.NestedType ||| MemberTypes.TypeInfo, bindingAttr)
+        match nt.Length with
+        | 0 -> null
+        | 1 -> downcast nt.[0]
+        | _ -> failwith (sprintf "There is more than one nested type called '%s' in type '%s'" name this.FullName)
+
+    // Attributes, etc..
+    override this.GetAttributeFlagsImpl() = adjustTypeAttributes attributes this.IsNested 
+    override this.IsArrayImpl() = false
+    override this.IsByRefImpl() = false
+    override this.IsPointerImpl() = false
+    override this.IsPrimitiveImpl() = false
+    override this.IsCOMObjectImpl() = false
+    override this.HasElementTypeImpl() = false
+    override this.UnderlyingSystemType = typeof<System.Type>
+    override this.Name = className
+    override this.DeclaringType = declaringType.Force()
+    override this.MemberType = if this.IsNested then MemberTypes.NestedType else MemberTypes.TypeInfo      
+    override this.GetHashCode() = rootNamespace.GetHashCode() ^^^ className.GetHashCode()
+    override this.Equals(that:obj) = 
+        match that with
+        | null              -> false
+        | :? ProvidedTypeDefinition as ti -> System.Object.ReferenceEquals(this,ti)
+        | _                 -> false
+
+    override this.GetGenericArguments() = [||] 
+    override this.ToString() = this.FullName
+    
+
+    override this.Module : Module = notRequired "Module" this.Name
+    override this.GUID                                                                                   = Guid.Empty
+    override this.GetConstructorImpl(_bindingAttr, _binder, _callConvention, _types, _modifiers)         = null
+    override this.GetCustomAttributes(_inherit)                                                          = [| |]
+    override this.GetCustomAttributes(_attributeType, _inherit)                                          = [| |]
+    override this.IsDefined(_attributeType: Type, _inherit)                                              = false
+
+    override this.GetElementType()                                                                                  = notRequired "Module" this.Name
+    override this.InvokeMember(_name, _invokeAttr, _binder, _target, _args, _modifiers, _culture, _namedParameters) = notRequired "Module" this.Name
+    override this.AssemblyQualifiedName                                                                             = notRequired "Module" this.Name
+    member this.IsErased 
+        with get() = (attributes &&& enum (int32 TypeProviderTypeAttributes.IsErased)) <> enum 0
+        and set v = 
+           if v then attributes <- attributes ||| enum (int32 TypeProviderTypeAttributes.IsErased)
+           else attributes <- attributes &&& ~~~(enum (int32 TypeProviderTypeAttributes.IsErased))
+
+    member this.SuppressRelocation 
+        with get() = (attributes &&& enum (int32 TypeProviderTypeAttributes.SuppressRelocate)) <> enum 0
+        and set v = 
+           if v then attributes <- attributes ||| enum (int32 TypeProviderTypeAttributes.SuppressRelocate)
+           else attributes <- attributes &&& ~~~(enum (int32 TypeProviderTypeAttributes.SuppressRelocate))
+
+    static member RegisterGenerated (fileName:string) = 
+        let assemblyBytes = System.IO.File.ReadAllBytes fileName
+        let assembly = Assembly.Load(assemblyBytes,null,System.Security.SecurityContextSource.CurrentAppDomain)
+        GlobalProvidedAssemblyElementsTable.theTable.Add(assembly, assemblyBytes)
+        assembly
+
+    /// Emit the given provided type definitions into an assembly and adjust 'Assembly' property of all type definitions to return that
+    /// assembly.
+    member this.ConvertToGenerated (assemblyFileName: string, ?reportAssemblyElements) = 
+        if this.IsErased then invalidOp ("The provided type "+this.Name+"is marked as erased and cannot be converted to a generated type. Set 'IsErased' to false on the ProvidedTypeDefinition")
+        let typeDefinitions = [this]
+        let theElementsLazy = 
+           lazy 
+              let assemblyShortName = Path.GetFileNameWithoutExtension assemblyFileName
+              let assemblyName = AssemblyName assemblyShortName
+              let assembly = 
+                  System.AppDomain.CurrentDomain.DefineDynamicAssembly(name=assemblyName,access=AssemblyBuilderAccess.Save,dir=Path.GetDirectoryName assemblyFileName)
+              let assemblyMainModule = 
+                  assembly.DefineDynamicModule("MainModule", Path.GetFileName assemblyFileName)
+              let typeMap = Dictionary(HashIdentity.Reference)
+
+              // phase 1 - set assembly fields and emit type definitions
+              begin 
+                  let rec typeMembers (tb:TypeBuilder)  (td : ProvidedTypeDefinition) = 
+                      for ntd in td.GetNestedTypes(BindingFlags.Public ||| BindingFlags.NonPublic) do
+                          nestedType tb ntd
+
+                  and nestedType (tb:TypeBuilder)  (ntd : Type) = 
+                      match ntd with 
+                      | :? ProvidedTypeDefinition as pntd -> 
+                          if pntd.IsErased then invalidOp ("The nested provided type "+pntd.Name+"is marked as erased and cannot be converted to a generated type. Set 'IsErased' to false on the ProvidedTypeDefinition")
+                          // Adjust the attributes - we're codegen'ing this type as nested
+                          let attributes = adjustTypeAttributes ntd.Attributes true
+                          let ntb = tb.DefineNestedType(pntd.Name,attr=attributes)
+                          pntd.SetAssembly null
+                          typeMap.[pntd] <- ntb
+                          typeMembers ntb pntd
+                      | _ -> ()
+                     
+                  for td in typeDefinitions do 
+                      // Filter out the additional TypeProviderTypeAttributes flags
+                      let attributes = td.Attributes &&& ~~~(enum (int32 TypeProviderTypeAttributes.SuppressRelocate))
+                                                     &&& ~~~(enum (int32 TypeProviderTypeAttributes.IsErased))
+                      // Adjust the attributes - we're codegen'ing as non-nested
+                      let attributes = adjustTypeAttributes attributes false 
+                      let tb = assemblyMainModule.DefineType(name=td.FullName,attr=attributes) 
+                      td.SetAssembly null
+                      typeMap.[td] <- tb
+                      typeMembers tb td 
+              end
+              let rec convType (ty:Type) = 
+                  match ty with 
+                  | :? ProvidedTypeDefinition as ptd ->   
+                      if typeMap.ContainsKey ptd then typeMap.[ptd] :> Type else ty
+                  | _ -> 
+                      if ty.IsGenericType then ty.GetGenericTypeDefinition().MakeGenericType (Array.map convType (ty.GetGenericArguments()))
+                      elif ty.HasElementType then 
+                         let ety = convType (ty.GetElementType()) 
+                         if ty.IsArray then 
+                             let rank = ty.GetArrayRank()
+                             if rank = 1 then ety.MakeArrayType() 
+                             else ety.MakeArrayType rank 
+                          elif ty.IsPointer then ety.MakePointerType() 
+                          elif ty.IsByRef then ety.MakeByRefType()
+                          else ty
+                      else ty
+
+              let ctorMap = Dictionary<ProvidedConstructor, ConstructorBuilder>(HashIdentity.Reference)
+              let methMap = Dictionary<ProvidedMethod, MethodBuilder>(HashIdentity.Reference)
+
+              let iterateTypes f = 
+                  let rec typeMembers (ptd : ProvidedTypeDefinition) = 
+                      let tb = typeMap.[ptd] 
+                      f tb ptd
+                      for ntd in ptd.GetNestedTypes(BindingFlags.Public ||| BindingFlags.NonPublic) do
+                          nestedType ntd
+
+                  and nestedType (ntd : Type) = 
+                      match ntd with 
+                      | :? ProvidedTypeDefinition as pntd -> typeMembers pntd
+                      | _ -> ()
+                     
+                  for td in typeDefinitions do 
+                      typeMembers td 
+
+              // phase 2 - emit member definitions
+              iterateTypes (fun tb ptd -> 
+                  let defineMeth (minfo:MethodInfo) = 
+                      match minfo with 
+                      | :? ProvidedMethod as pminfo when not (methMap.ContainsKey pminfo)  -> 
+                          let mb = tb.DefineMethod(minfo.Name, minfo.Attributes, convType minfo.ReturnType, [| for p in minfo.GetParameters() -> convType p.ParameterType |])
+                          //, CallingConventions.Standard, [| for p in cinfo.GetParameters() -> convType p.ParameterType |])
+                          methMap.[pminfo] <- mb
+                      | _ -> () 
+                  for cinfo in ptd.GetConstructors(BindingFlags.Public ||| BindingFlags.NonPublic) do
+                      match cinfo with 
+                      | :? ProvidedConstructor as pcinfo when not (ctorMap.ContainsKey pcinfo)  -> 
+                          let cb = tb.DefineConstructor(cinfo.Attributes, CallingConventions.Standard, [| for p in cinfo.GetParameters() -> convType p.ParameterType |])
+                          ctorMap.[pcinfo] <- cb
+                      | _ -> () 
+                    
+                  for minfo in ptd.GetMethods(BindingFlags.Public ||| BindingFlags.NonPublic) do
+                      defineMeth minfo
+
+                  for ityp in ptd.GetInterfaceImplementations() do
+                      tb.AddInterfaceImplementation ityp)
+
+              // phase 3 - emit member code
+              iterateTypes (fun  tb ptd -> 
+                  // Allow at most one constructor, and use its arguments as the fields of the type
+                  let ctorArgs, ctorInfoOpt =
+                      match ptd.GetConstructors(BindingFlags.Public ||| BindingFlags.NonPublic) |> Seq.toList with 
+                      | [] -> [], None
+                      | [ :? ProvidedConstructor as pcinfo ] -> [ for p in pcinfo.GetParameters() -> p ], Some pcinfo
+                      | _ -> failwith "at most one constructor allowed"
+                  let ctorArgsAsFields = [ for ctorArg in ctorArgs -> tb.DefineField(ctorArg.Name, convType ctorArg.ParameterType, FieldAttributes.Private) ]
+
+                  // Emit the constructor (if any)
+                  match ctorInfoOpt with 
+                  | None -> ()
+                  | Some pcinfo -> 
+                
+                      assert ctorMap.ContainsKey pcinfo
+                      let cb = ctorMap.[pcinfo]
+                      let ilg = cb.GetILGenerator()
+                      ilg.Emit(OpCodes.Ldarg_0)
+                      let minfo = typeof<obj>.GetConstructor [| |]
+                      ilg.Emit(OpCodes.Call,minfo)
+                      for ctorArgsAsFieldIdx,ctorArgsAsField in List.mapi (fun i x -> (i,x)) ctorArgsAsFields do 
+                          ilg.Emit(OpCodes.Ldarg_0)
+                          ilg.Emit(OpCodes.Ldarg, ctorArgsAsFieldIdx+1)
+                          ilg.Emit(OpCodes.Stfld, ctorArgsAsField)
+                    
+                      ilg.Emit(OpCodes.Ret)
+                    
+                  // Emit the methods
+                  let emitMethod (minfo:MethodInfo) = 
+                    match minfo with 
+                    | :? ProvidedMethod as pminfo   -> 
+                      let mb = methMap.[pminfo]
+                      let ilg = mb.GetILGenerator()
+                      let pop () = ilg.Emit(OpCodes.Pop)
+
+                      let parameterVars = 
+                          [| if not pminfo.IsStatic then 
+                                 yield Quotations.Var("this", pminfo.DeclaringType)
+                             for p in pminfo.GetParameters() do 
+                                 yield Quotations.Var(p.Name, p.ParameterType) |]
+                      let parameters = 
+                          [| for v in parameterVars -> Quotations.Expr.Var v |]
+                      let linqCode = pminfo.InvokeCodeInternal parameters
+                      let locals = Dictionary<Quotations.Var,LocalBuilder>()
+                      //printfn "Emitting linqCode for %s::%s, code = %s" pminfo.DeclaringType.FullName pminfo.Name (try linqCode.ToString() with _ -> "<error>")
+
+                      /// emits given expression to corresponding IL
+                      /// callerDontNeedResult - if true then caller will not use result of this expression so it needs to be discarded
+                      let rec emit (callerDontNeedResult : bool) (expr: Quotations.Expr) = 
+                          match expr with 
+                          | Quotations.Patterns.Var v -> 
+                              if callerDontNeedResult then ()
+                              else
+                              let methIdx = parameterVars |> Array.tryFindIndex (fun p -> p = v) 
+                              match methIdx with 
+                              | Some idx -> ilg.Emit(OpCodes.Ldarg, idx)
+                              | None -> 
+                              let ctorArgFieldOpt = ctorArgsAsFields |> List.tryFind (fun f -> f.Name = v.Name) 
+                              match ctorArgFieldOpt with 
+                              | Some ctorArgField -> 
+                                  ilg.Emit(OpCodes.Ldarg_0)
+                                  ilg.Emit(OpCodes.Ldfld, ctorArgField)
+                              | None -> 
+                              match locals.TryGetValue v with 
+                              | true, localBuilder -> 
+                                  ilg.Emit(OpCodes.Ldloc, localBuilder.LocalIndex)
+                              | false, _ -> 
+                                  failwith "unknown parameter/field"
+                          | Quotations.Patterns.Coerce (arg,ty) -> 
+                              if callerDontNeedResult then ()
+                              else
+                              emit false arg
+                              ilg.Emit(OpCodes.Castclass , convType ty)
+                          | Quotations.Patterns.Call (objOpt,meth,args) -> 
+                              match objOpt with None -> () | Some e -> emit false e
+                              for pe in args do 
+                                  emit false pe
+                              let meth = match meth with :? ProvidedMethod as pm when methMap.ContainsKey pm -> methMap.[pm] :> MethodInfo | m -> m
+                              ilg.Emit((if meth.IsAbstract || meth.IsVirtual then  OpCodes.Callvirt else OpCodes.Call), meth)
+                              let returnTypeIsVoid = meth.ReturnType = typeof<System.Void>
+                              match returnTypeIsVoid, callerDontNeedResult with
+                              | false, true -> 
+                                    // method produced something, but we don't need it
+                                    pop()
+                              | true, false when expr.Type = typeof<unit> -> 
+                                    // if we need result and method produce void and result should be unit - push null as unit value on stack
+                                    ilg.Emit(OpCodes.Ldnull)
+                              | _ -> ()
+
+                          | Quotations.Patterns.NewObject (ctor,args) -> 
+                              for pe in args do 
+                                  emit false pe
+                              let meth = match ctor with :? ProvidedConstructor as pc when ctorMap.ContainsKey pc -> ctorMap.[pc] :> ConstructorInfo | c -> c
+                              ilg.Emit(OpCodes.Newobj, meth)
+                              if callerDontNeedResult then pop()
+
+                          | Quotations.Patterns.Value (obj, _ty) -> 
+                              let rec emitC (v:obj) = 
+                                  match v with 
+                                  | :? string as x -> ilg.Emit(OpCodes.Ldstr, x)
+                                  | :? int8 as x -> ilg.Emit(OpCodes.Ldc_I4, int32 x)
+                                  | :? uint8 as x -> ilg.Emit(OpCodes.Ldc_I4, int32 (int8 x))
+                                  | :? int16 as x -> ilg.Emit(OpCodes.Ldc_I4, int32 x)
+                                  | :? uint16 as x -> ilg.Emit(OpCodes.Ldc_I4, int32 (int16 x))
+                                  | :? int32 as x -> ilg.Emit(OpCodes.Ldc_I4, x)
+                                  | :? uint32 as x -> ilg.Emit(OpCodes.Ldc_I4, int32 x)
+                                  | :? int64 as x -> ilg.Emit(OpCodes.Ldc_I8, x)
+                                  | :? uint64 as x -> ilg.Emit(OpCodes.Ldc_I8, int64 x)
+                                  | :? char as x -> ilg.Emit(OpCodes.Ldc_I4, int32 x)
+                                  | :? bool as x -> ilg.Emit(OpCodes.Ldc_I4, if x then 1 else 0)
+                                  | :? System.Enum as x when x.GetType().GetEnumUnderlyingType() = typeof<int32> -> ilg.Emit(OpCodes.Ldc_I4, unbox<int32> v)
+                                  | null -> ilg.Emit(OpCodes.Ldnull)
+                                  | _ -> failwithf "unknown constant '%A' in generated method" v
+                              if callerDontNeedResult then ()
+                              else emitC obj
+                          | Quotations.Patterns.Let(v,e,b) -> 
+                              let lb = ilg.DeclareLocal v.Type
+                              locals.Add (v, lb) 
+                              emit false e
+                              ilg.Emit(OpCodes.Stloc, lb.LocalIndex)
+                              emit callerDontNeedResult b
+                              
+                          | Quotations.Patterns.Sequential(e1, e2) ->
+                              emit true e1
+                              emit callerDontNeedResult e2                          
+                          | Quotations.Patterns.IfThenElse(cond, ifTrue, ifFalse) ->
+                              let ifFalseLabel = ilg.DefineLabel()
+                              let endLabel = ilg.DefineLabel()
+
+                              emit false cond
+
+                              ilg.Emit(OpCodes.Brfalse, ifFalseLabel)
+
+                              emit callerDontNeedResult ifTrue
+                              ilg.Emit(OpCodes.Br, endLabel)
+
+                              ilg.MarkLabel(ifFalseLabel)
+                              emit callerDontNeedResult ifFalse
+
+                              ilg.Emit(OpCodes.Nop)
+                              ilg.MarkLabel(endLabel)
+
+                          | Quotations.Patterns.TryWith(body, _filterVar, _filterBody, catchVar, catchBody) ->                                                                                      
+                              
+                              let stres, ldres = 
+                                  if callerDontNeedResult then ignore, ignore
+                                  else
+                                    let local = ilg.DeclareLocal body.Type
+                                    let stres = fun () -> ilg.Emit(OpCodes.Stloc, local)
+                                    let ldres = fun () -> ilg.Emit(OpCodes.Ldloc, local)
+                                    stres, ldres
+
+                              let exceptionVar = ilg.DeclareLocal(catchVar.Type)
+                              locals.Add(catchVar, exceptionVar)
+
+                              let _exnBlock = ilg.BeginExceptionBlock()
+                              
+                              emit callerDontNeedResult body
+                              stres()
+
+                              ilg.BeginCatchBlock(catchVar.Type)
+                              ilg.Emit(OpCodes.Stloc, exceptionVar)
+                              emit callerDontNeedResult catchBody
+                              stres()
+                              ilg.EndExceptionBlock()
+
+                              ldres()
+
+                          | Quotations.Patterns.VarSet(v,e) -> 
+                              emit false e
+                              match locals.TryGetValue v with 
+                              | true, localBuilder -> 
+                                  ilg.Emit(OpCodes.Stloc, localBuilder.LocalIndex)
+                              | false, _ -> 
+                                  failwith "unknown parameter/field in assignment. Only assignments to locals are currently supported by TypeProviderEmit"
+                          | n -> 
+                              failwith (sprintf "unknown expression '%A' in generated method" n)
+
+                      let callerDontNeedResult = (minfo.ReturnType = typeof<System.Void>)
+                      emit callerDontNeedResult linqCode
+                      ilg.Emit OpCodes.Ret
+                    | _ -> ()
+  
+                  for minfo in ptd.GetMethods(BindingFlags.Public ||| BindingFlags.NonPublic) do
+                      emitMethod minfo
+
+                  for (bodyMethInfo,declMethInfo) in ptd.GetMethodOverrides() do 
+                     let bodyMethBuilder = methMap.[bodyMethInfo]
+                     tb.DefineMethodOverride(bodyMethBuilder,declMethInfo)
+
+                  for pinfo in ptd.GetProperties(BindingFlags.Public ||| BindingFlags.NonPublic) do
+                      let pb = tb.DefineProperty(pinfo.Name, pinfo.Attributes, convType pinfo.PropertyType, [| for p in pinfo.GetIndexParameters() -> convType p.ParameterType |])
+                      if  pinfo.CanRead then 
+                          let minfo = pinfo.GetGetMethod(true)
+                          pb.SetGetMethod (methMap.[minfo :?> ProvidedMethod ])
+                      if  pinfo.CanWrite then 
+                          let minfo = pinfo.GetSetMethod(true)
+                          pb.SetSetMethod (methMap.[minfo :?> ProvidedMethod ]))
+
+              // phase 4 - complete types
+              iterateTypes (fun tb _ptd -> tb.CreateType() |> ignore)
+
+
+              assembly.Save (Path.GetFileName assemblyFileName)
+              let assemblyBytes = File.ReadAllBytes assemblyFileName
+              let assemblyLoadedInMemory = System.Reflection.Assembly.Load(assemblyBytes,null,System.Security.SecurityContextSource.CurrentAppDomain)
+              File.Delete assemblyFileName
+
+              iterateTypes (fun _tb ptd -> ptd.SetAssembly assemblyLoadedInMemory)
+
+              match reportAssemblyElements with 
+              | None -> GlobalProvidedAssemblyElementsTable.theTable.Add(assemblyLoadedInMemory, assemblyBytes) 
+              | Some f -> f (assemblyLoadedInMemory, assemblyBytes)
+              assemblyLoadedInMemory
+
+        theAssembly <- theElementsLazy
+
+
+
+
+#if PROVIDER_TRANSFORMATIONS
+type Context = { EventFilter : (EventInfo -> bool)
+                 PropertyFilter : (PropertyInfo -> bool)
+                 FieldFilter : (FieldInfo -> bool)
+                 ConstructorFilter : (ConstructorInfo -> bool) 
+                 MethodFilter : (MethodInfo -> bool) 
+                 BaseTypeTransform : (Type -> Type option) }
+
+
+module Filtered = 
+    let FilterTypes (ctxt:Context) = 
+        let collectNonNull f xs = Array.choose (fun x -> match f x with null -> None | v -> Some v) xs
+        let rec fAssembly(x: System.Reflection.Assembly) =
+            match x with 
+            | null -> null 
+            | _ -> 
+            { new System.Reflection.Assembly() with 
+                override this.GetTypes() = x.GetTypes() |> fTypes 
+                override this.ManifestModule = x.ManifestModule 
+
+                override this.FullName = x.FullName
+                override this.GetName() = x.GetName() 
+                override this.ToString() = x.ToString() }
+
+        and fMethod(x: System.Reflection.MethodInfo) =
+            match x with 
+            | null -> null 
+            | _ -> 
+            if not (ctxt.MethodFilter x) then null else 
+            { new System.Reflection.MethodInfo() with 
+                override this.DeclaringType = x.DeclaringType  |> fType
+                override this.GetParameters() = x.GetParameters() |> fParams
+
+                override this.CallingConvention =  x.CallingConvention
+                override this.ReturnType = x.ReturnType
+                override this.ToString() = x.ToString()
+                override __.GetCustomAttributesData() = x.GetCustomAttributesData()
+
+                override this.ReturnParameter = x.ReturnParameter |> fParam
+                override this.Name = x.Name 
+                override this.Attributes = x.Attributes
+                override this.ReturnTypeCustomAttributes                           = notRequired "ReturnTypeCustomAttributes" this.Name
+                override this.GetBaseDefinition()                                  = notRequired "GetBaseDefinition" this.Name
+                override this.IsDefined(_attributeType, _inherit)                = notRequired "IsDefined" this.Name
+                override this.Invoke(obj, invokeAttr, binder, parameters, culture) = notRequired "Invoke" this.Name
+                override this.ReflectedType                                        = notRequired "ReflectedType" this.Name
+                override this.GetMethodImplementationFlags()                       = notRequired "GetMethodImplementationFlags" this.Name
+                override this.MethodHandle                                         = notRequired "MethodHandle" this.Name
+                override this.GetCustomAttributes(_inherit)                     = notRequired "GetCustomAttributes" this.Name
+                override this.GetCustomAttributes(_attributeType, _inherit)      = notRequired "GetCustomAttributes" this.Name }
+
+        and fProp(x: System.Reflection.PropertyInfo) =
+            match x with 
+            | null -> null 
+            | _ -> 
+            if not (ctxt.PropertyFilter x) then null else 
+            { new System.Reflection.PropertyInfo() with
+                override this.DeclaringType = x.DeclaringType  |> fType
+                override this.PropertyType = x.PropertyType |> fType 
+                override this.GetGetMethod nonPublic = x.GetGetMethod nonPublic |> fMethod
+                override this.GetSetMethod nonPublic = x.GetSetMethod nonPublic |> fMethod
+                override this.GetIndexParameters() = x.GetIndexParameters() |> fParams
+
+                override this.Name = x.Name
+                override this.Attributes = x.Attributes
+                override this.CanRead = x.CanRead
+                override this.CanWrite = x.CanWrite
+                override this.MemberType = x.MemberType
+                override this.ToString() = x.ToString()
+                override this.GetCustomAttributesData() = x.GetCustomAttributesData()
+
+                override this.GetValue(obj, invokeAttr, binder, index, culture) : obj = notRequired "GetValue" this.Name
+                override this.GetAccessors nonPublic  = notRequired "nonPublic" this.Name
+                override this.SetValue(obj, value, invokeAttr, binder, index, culture) = notRequired "SetValue" this.Name
+                override this.ReflectedType                                     = notRequired "ReflectedType" this.Name
+                override this.GetCustomAttributes(_inherit)                  = notRequired "GetCustomAttributes" this.Name
+                override this.GetCustomAttributes(_attributeType, _inherit)   = notRequired "GetCustomAttributes" this.Name 
+                override this.IsDefined(_attributeType, _inherit)             = notRequired "IsDefined" this.Name }
+
+        and fField(x: System.Reflection.FieldInfo) =
+            match x with 
+            | null -> null 
+            | _ -> 
+            if not (ctxt.FieldFilter x) then null else 
+            { new System.Reflection.FieldInfo() with
+                override this.DeclaringType = x.DeclaringType  |> fType
+                override this.FieldType = x.FieldType |> fType 
+
+                override this.Name = x.Name 
+                override this.FieldHandle = x.FieldHandle
+                override this.ToString() = x.ToString()
+                override this.GetCustomAttributesData() = x.GetCustomAttributesData()
+
+                override this.Attributes = x.Attributes
+                override this.ReflectedType                                     = notRequired "ReflectedType" this.Name
+                override this.GetValue(a)                                       = notRequired "GetValue" this.Name
+                override this.SetValue(a,b,c,d,e)                               = notRequired "SetValue" this.Name
+                override this.GetCustomAttributes(_inherit)                  = notRequired "GetCustomAttributes" this.Name
+                override this.GetCustomAttributes(_attributeType, _inherit)   = notRequired "GetCustomAttributes" this.Name 
+                override this.IsDefined(_attributeType, _inherit)             = notRequired "IsDefined" this.Name }
+
+        and fCtor(x: System.Reflection.ConstructorInfo) =
+            match x with 
+            | null -> null 
+            | _ -> 
+            if not (ctxt.ConstructorFilter x) then null else 
+            { new System.Reflection.ConstructorInfo() with 
+                override this.DeclaringType = x.DeclaringType  |> fType
+                override this.GetParameters() = x.GetParameters () |> fParams
+
+                override this.Name = x.Name 
+                override this.Attributes = x.Attributes
+                override this.ToString() = x.ToString()
+                override this.GetCustomAttributesData() = x.GetCustomAttributesData()
+
+                override this.IsDefined(_attributeType, _inherit) = notRequired "IsDefined" ".ctor"
+                override this.Invoke(invokeAttr, binder, parameters, culture)      = notRequired "Invoke" ".ctor"
+                override this.Invoke(obj, invokeAttr, binder, parameters, culture) = notRequired "Invoke" ".ctor"
+                override this.ReflectedType                                        = notRequired "ReflectedType" ".ctor"
+                override this.GetMethodImplementationFlags()                       = notRequired "GetMethodImplementationFlags" ".ctor"
+                override this.MethodHandle                                         = notRequired "MethodHandle" ".ctor"
+                override this.GetCustomAttributes(_inherit)                     = notRequired "GetCustomAttributes" ".ctor"
+                override this.GetCustomAttributes(_attributeType, _inherit)      = notRequired "GetCustomAttributes" ".ctor" }
+
+
+        and fEvent(x: System.Reflection.EventInfo) =
+            match x with 
+            | null -> null 
+            | _ -> 
+            if not (ctxt.EventFilter x) then null else 
+            { new System.Reflection.EventInfo() with 
+                override this.DeclaringType = x.DeclaringType  |> fType
+                override this.EventHandlerType = x.EventHandlerType |> fType 
+                override this.GetRaiseMethod nonPublic = x.GetRaiseMethod nonPublic |> fMethod
+                override this.GetAddMethod nonPublic = x.GetAddMethod nonPublic |> fMethod
+                override this.GetRemoveMethod nonPublic = x.GetRemoveMethod nonPublic |> fMethod
+
+                override this.Name = x.Name 
+                override this.IsMulticast = x.IsMulticast 
+                override this.GetCustomAttributesData() = x.GetCustomAttributesData()
+
+                override this.Attributes = x.Attributes
+                override this.ReflectedType                                     = notRequired "ReflectedType" this.Name
+                override this.GetCustomAttributes(_inherit)                  = notRequired "GetCustomAttributes" this.Name
+                override this.GetCustomAttributes(_attributeType, _inherit)   = notRequired "GetCustomAttributes" this.Name 
+                override this.IsDefined(_attributeType, _inherit)             = notRequired "IsDefined" this.Name }
+
+        and fBaseType (x: Type) =
+            match x with 
+            | null -> null 
+            | _ -> 
+            match ctxt.BaseTypeTransform x with None -> fType x | Some ty -> ty
+
+        and fParam(x: System.Reflection.ParameterInfo) =
+            match x with 
+            | null -> null 
+            | _ -> 
+            { new System.Reflection.ParameterInfo() with 
+                override this.Name = x.Name 
+                override this.ParameterType = x.ParameterType |> fType 
+
+                override this.RawDefaultValue = x.RawDefaultValue
+                override this.Attributes = x.Attributes
+                override this.Position = x.Position
+                override this.GetCustomAttributesData() = x.GetCustomAttributesData()
+                override this.GetCustomAttributes(_inherit) = notRequired "GetCustomAttributes" x.Name
+                override this.GetCustomAttributes(_attributeType, _inherit) = notRequired "GetCustomAttributes" x.Name }
+
+        and fMethods xs = collectNonNull fMethod xs
+        and fEvents xs = collectNonNull fEvent xs
+        and fCtors xs = collectNonNull fCtor xs
+        and fFields xs = collectNonNull fField xs
+        and fProps xs = collectNonNull fProp xs
+
+        and fTypes xs = Array.map fType xs
+        and fParams xs = Array.map fParam xs
+
+        and fType(x: System.Type) =
+            match x with 
+            | null -> null 
+            | _ -> 
+            { new System.Type() with 
+                override this.Assembly                    =  x.Assembly |> fAssembly
+                override this.GetConstructors bindingAttr = x.GetConstructors bindingAttr |> fCtors
+                override this.GetMethods bindingAttr      = x.GetMethods bindingAttr |> fMethods
+                override this.GetField(name, bindingAttr) = x.GetField (name, bindingAttr) |> fField
+                override this.GetFields bindingAttr       = x.GetFields bindingAttr |> fFields
+                override this.GetInterfaces()             = x.GetInterfaces() |> fTypes
+                override this.GetEvent(name, bindingAttr) = x.GetEvent(name, bindingAttr) |> fEvent
+                override this.GetEvents bindingAttr       = x.GetEvents bindingAttr |> fEvents
+
+                override this.GetProperties bindingAttr        = x.GetProperties bindingAttr |> fProps
+                override this.GetNestedTypes bindingAttr       = x.GetNestedTypes bindingAttr |> fTypes
+                override this.GetNestedType(name, bindingAttr) = x.GetNestedType (name, bindingAttr) |> fType
+                override this.DeclaringType                    = x.DeclaringType |> fType
+                override this.GetGenericArguments()            = x.GetGenericArguments() |> fTypes
+                override this.GetGenericTypeDefinition()       = x.GetGenericTypeDefinition() |> fType
+                override this.BaseType                         = x.BaseType |> fBaseType
+                override this.GetElementType()                 = x.GetElementType() |> fType
+
+                override this.GetPropertyImpl(name, bindingAttr, binder, returnType, types, modifiers) = 
+                   x.GetProperty(name, bindingAttr, binder, returnType, (match types with null -> [| |] | _ -> types), modifiers) |> fProp
+                override this.GetConstructorImpl(bindingAttr, binder, callConvention, types, modifiers) = 
+                    x.GetConstructor(bindingAttr, binder, callConvention, (match types with null -> [| |] | _ -> types), modifiers) |> fCtor
+
+                override this.MakeArrayType() = ProvidedSymbolType(SymbolKind.SDArray, [this]) :> Type
+                override this.MakeArrayType arg = ProvidedSymbolType(SymbolKind.Array arg, [this]) :> Type
+                override this.MakePointerType() = ProvidedSymbolType(SymbolKind.Pointer, [this]) :> Type
+                override this.MakeByRefType() = ProvidedSymbolType(SymbolKind.ByRef, [this]) :> Type
+                override this.MakeGenericType(args) = ProvidedSymbolType(SymbolKind.Generic this, Array.toList args) :> Type
+
+                override this.GetCustomAttributesData() = x.GetCustomAttributesData()
+                override this.FullName = x.FullName
+                override this.Namespace = x.Namespace
+                override this.GetAttributeFlagsImpl() = x.Attributes
+                override this.IsGenericType = x.IsGenericType
+                override this.IsGenericParameter = x.IsGenericParameter
+                override this.IsGenericTypeDefinition = x.IsGenericTypeDefinition
+                override this.IsArrayImpl() = x.IsArray
+                override this.IsByRefImpl() = x.IsByRef
+                override this.IsPointerImpl() = x.IsPointer
+                override this.IsPrimitiveImpl() = x.IsPrimitive
+                override this.IsCOMObjectImpl() = x.IsCOMObject
+                override this.HasElementTypeImpl() = x.HasElementType
+                override this.UnderlyingSystemType = x.UnderlyingSystemType
+                override this.Name : string = x.Name
+                override this.MemberType = x.MemberType
+                override this.GetHashCode() = x.GetHashCode()
+                override this.Equals(that:obj) = x.Equals(that)
+                override this.ToString() = x.ToString()
+
+                override this.GetMembers bindingAttr =  notRequired "GetMembers" this.Name
+                override this.GetInterface(name, ignoreCase) = notRequired "GetInterface" this.Name
+                override this.GetMember(name,mt,bindingAttr) = notRequired "GetMember" this.Name
+                override this.GetMethodImpl(name, bindingAttr, binderBinder, callConvention, types, modifiers) = notRequired "GetMethodImpl" this.Name
+                override this.Module : Module = notRequired "Module" this.Name
+                override this.GUID                                                                                      = x.GUID
+                override this.GetCustomAttributes(_inherit)                                                          = x.GetCustomAttributes(_inherit)
+                override this.GetCustomAttributes(_attributeType, _inherit)                                           = x.GetCustomAttributes(_attributeType, _inherit)
+                override this.IsDefined(attributeType: Type, _inherit)                                               = x.IsDefined(_attributeType, _inherit)
+
+                override this.InvokeMember(name, invokeAttr, binder, target, args, modifiers, culture, namedParameters) = x.InvokeMember(name, invokeAttr, binder, target, args, modifiers, culture, namedParameters)
+                override this.AssemblyQualifiedName                                                                     = x.AssemblyQualifiedName
+                }
+
+        fTypes  
+
+[<Sealed;Class;AbstractClass>]
+type ProviderTransformations() = 
+    static member FilterTypes (types,?methodFilter,?eventFilter,?propertyFilter,?constructorFilter,?fieldFilter,?baseTypeTransform) = 
+        let ctxt = 
+            { EventFilter = defaultArg eventFilter (fun _ -> true)
+              PropertyFilter = defaultArg propertyFilter (fun _ -> true)
+              FieldFilter = defaultArg fieldFilter (fun _ -> true)
+              ConstructorFilter =  defaultArg constructorFilter (fun _ -> true)
+              MethodFilter  =  defaultArg methodFilter (fun _ -> true);
+              BaseTypeTransform = defaultArg baseTypeTransform (fun _ -> None) }
+        Filtered.FilterTypes ctxt (Array.ofList types) |> Array.toList
+
+#endif
+
+#if TPEMIT_INTERNAL_AND_MINIMAL_FOR_TYPE_CONTAINERS
+#else
+module Local = 
+
+    let makeProvidedNamespace (namespaceName:string) (types:ProvidedTypeDefinition list) =
+        let types = [| for ty in types -> ty :> Type |]
+        {new IProvidedNamespace with
+            member __.GetNestedNamespaces() = [| |]
+            member __.NamespaceName = namespaceName
+            member __.GetTypes() = types |> Array.copy
+            member __.ResolveTypeName typeName : System.Type = 
+                match types |> Array.tryFind (fun ty -> ty.Name = typeName) with
+                | Some ty -> ty
+                | None    -> let typenames = String.concat "," (types |> Array.map (fun t -> t.Name))
+                             failwith (sprintf "Unknown type '%s' in namespace '%s' (contains %s)" typeName namespaceName typenames)    
+        }
+
+
+type TypeProviderForNamespaces(namespacesAndTypes : list<(string * list<ProvidedTypeDefinition>)>) =
+    let otherNamespaces = ResizeArray<string * list<ProvidedTypeDefinition>>()
+
+    let providedNamespaces = 
+        lazy [| for (namespaceName,types) in namespacesAndTypes do 
+                     yield Local.makeProvidedNamespace namespaceName types 
+                for (namespaceName,types) in otherNamespaces do 
+                     yield Local.makeProvidedNamespace namespaceName types |]
+
+    let invalidateE = new Event<EventHandler,EventArgs>()    
+
+    new (namespaceName:string,types:list<ProvidedTypeDefinition>) = new TypeProviderForNamespaces([(namespaceName,types)])
+    new () = new TypeProviderForNamespaces([])
+
+    member __.AddNamespace (namespaceName,types:list<_>) = otherNamespaces.Add (namespaceName,types)
+    member self.Invalidate() = invalidateE.Trigger(self,EventArgs())
+    interface System.IDisposable with 
+        member x.Dispose() = ()
+    interface ITypeProvider with
+        [<CLIEvent>]
+        override this.Invalidate = invalidateE.Publish
+        override this.GetNamespaces() = Array.copy providedNamespaces.Value
+        member __.GetInvokerExpression(methodBase, parameters) = 
+            match methodBase with
+            | :? ProvidedMethod as m when (match methodBase.DeclaringType with :? ProvidedTypeDefinition as pt -> pt.IsErased | _ -> true) -> 
+                m.InvokeCodeInternal parameters
+            | :? ProvidedConstructor as m when (match methodBase.DeclaringType with :? ProvidedTypeDefinition as pt -> pt.IsErased | _ -> true) -> 
+                m.InvokeCodeInternal parameters
+            // Otherwise, assume this is a generative assembly and just emit a call to the constructor or method
+            | :?  ConstructorInfo as cinfo ->  
+                Quotations.Expr.NewObject(cinfo, Array.toList parameters) 
+            | :? System.Reflection.MethodInfo as minfo ->  
+                if minfo.IsStatic then 
+                    Quotations.Expr.Call(minfo, Array.toList parameters) 
+                else
+                    Quotations.Expr.Call(parameters.[0], minfo, Array.toList parameters.[1..])
+            | _ -> failwith ("TypeProviderForNamespaces.GetInvokerExpression: not a ProvidedMethod/ProvidedConstructor/ConstructorInfo/MethodInfo, name=" + methodBase.Name + " class=" + methodBase.GetType().FullName)
+
+        override this.GetStaticParameters(ty) =
+            match ty with
+            | :? ProvidedTypeDefinition as t ->
+                if ty.Name = t.Name (* REVIEW: use equality? *) then
+                    t.GetStaticParameters()
+                else
+                    [| |]
+            | _ -> [| |]
+
+        override this.ApplyStaticArguments(ty,typePathAfterArguments:string[],objs) = 
+            let typePathAfterArguments = typePathAfterArguments.[typePathAfterArguments.Length-1]
+            match ty with
+            | :? ProvidedTypeDefinition as t -> (t.MakeParametricType(typePathAfterArguments,objs) :> Type)
+            | _ -> failwith (sprintf "ApplyStaticArguments: static params for type %s are unexpected" ty.FullName)
+
+        override x.GetGeneratedAssemblyContents(assembly) = 
+            match GlobalProvidedAssemblyElementsTable.theTable.TryGetValue assembly with 
+            | true,bytes -> bytes
+            | _ -> 
+                let bytes = System.IO.File.ReadAllBytes assembly.ManifestModule.FullyQualifiedName
+                GlobalProvidedAssemblyElementsTable.theTable.[assembly] <- bytes
+                bytes
+
+#endif
+
diff --git a/vsintegration/src/unittests/Resources.MockTypeProviders/DummyProviderForLanguageServiceTesting/TypeProviderEmit.fsi b/vsintegration/src/unittests/Resources.MockTypeProviders/DummyProviderForLanguageServiceTesting/TypeProviderEmit.fsi
new file mode 100644
index 0000000..b599683
--- /dev/null
+++ b/vsintegration/src/unittests/Resources.MockTypeProviders/DummyProviderForLanguageServiceTesting/TypeProviderEmit.fsi
@@ -0,0 +1,283 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+#if TPEMIT_INTERNAL_AND_MINIMAL_FOR_TYPE_CONTAINERS
+namespace Internal.Utilities.TypeProvider.Emit
+#else
+namespace Microsoft.FSharp.TypeProvider.Emit
+#endif
+open System
+open System.Reflection
+open System.Linq.Expressions
+open Microsoft.FSharp.Core.CompilerServices
+
+
+/// Represents an erased provided parameter
+type ProvidedParameter =
+    inherit System.Reflection.ParameterInfo
+    new : parameterName: string * parameterType: Type * ?isOut:bool * ?optionalValue:obj -> ProvidedParameter
+    
+
+/// Represents an erased provided constructor.
+type ProvidedConstructor =    
+    inherit System.Reflection.ConstructorInfo
+
+    /// Create a new provided constructor. It is not initially associated with any specific provided type definition.
+    new : parameters: ProvidedParameter list -> ProvidedConstructor
+    
+    /// Add XML documentation information to this provided constructor
+    member AddXmlDoc          : xmlDoc: string -> unit   
+    
+    /// Add XML documentation information to this provided constructor, where the computation of the documentation is delayed until necessary
+    member AddXmlDocDelayed   : xmlDocFunction: (unit -> string) -> unit   
+    
+    /// Add XML documentation information to this provided constructor, where the documentation is re-computed  every time it is required.
+    member AddXmlDocComputed   : xmlDocFunction: (unit -> string) -> unit   
+    
+    /// Set the quotation used to compute the implementation of invocations of this constructor.
+    member InvokeCode         : (Quotations.Expr list -> Quotations.Expr) with set
+
+    /// Set the function used to compute the implementation of invocations of this constructor.
+    member InvokeCodeInternal         : (Quotations.Expr[] -> Quotations.Expr) with get,set
+
+    /// Add definition location information to the provided constructor.
+    member AddDefinitionLocation : line:int * column:int * filePath:string -> unit
+    
+
+type ProvidedMethod = 
+    inherit System.Reflection.MethodInfo
+
+    /// Create a new provided method. It is not initially associated with any specific provided type definition.
+    new : methodName:string * parameters: ProvidedParameter list * returnType: Type -> ProvidedMethod
+
+    /// Add XML documentation information to this provided constructor
+    member AddXmlDoc            : xmlDoc: string -> unit    
+
+    /// Add XML documentation information to this provided constructor, where the computation of the documentation is delayed until necessary
+    member AddXmlDocDelayed   : xmlDocFunction: (unit -> string) -> unit   
+    
+    /// Add XML documentation information to this provided constructor, where the computation of the documentation is delayed until necessary
+    /// The documentation is re-computed  every time it is required.
+    member AddXmlDocComputed   : xmlDocFunction: (unit -> string) -> unit   
+    
+    member AddMethodAttrs       : attributes:MethodAttributes -> unit
+
+    /// Set the method attributes of the method. By default these are simple 'MethodAttributes.Public'
+    member SetMethodAttrs       : attributes:MethodAttributes -> unit
+
+    /// Get or set a flag indicating if the property is static.
+    member IsStaticMethod       : bool with get, set
+
+    /// Set the quotation used to compute the implementation of invocations of this method.
+    member InvokeCode         : (Quotations.Expr list -> Quotations.Expr) with set
+
+    /// Set the function used to compute the implementation of invocations of this method.
+    member InvokeCodeInternal         : (Quotations.Expr[] -> Quotations.Expr) with get,set
+
+
+    /// Add definition location information to the provided type definition.
+    member AddDefinitionLocation : line:int * column:int * filePath:string -> unit
+
+
+/// Represents an erased provided property.
+type ProvidedProperty =
+    inherit System.Reflection.PropertyInfo
+
+    /// Create a new provided type. It is not initially associated with any specific provided type definition.
+    new  : propertyName: string * propertyType: Type * ?parameters:ProvidedParameter list -> ProvidedProperty
+
+    /// Add XML documentation information to this provided constructor
+    member AddXmlDoc            : xmlDoc: string -> unit    
+
+    /// Add XML documentation information to this provided constructor, where the computation of the documentation is delayed until necessary
+    member AddXmlDocDelayed   : xmlDocFunction: (unit -> string) -> unit   
+    
+    /// Add XML documentation information to this provided constructor, where the computation of the documentation is delayed until necessary
+    /// The documentation is re-computed  every time it is required.
+    member AddXmlDocComputed   : xmlDocFunction: (unit -> string) -> unit   
+    
+    /// Get or set a flag indicating if the property is static.
+    member IsStatic             : bool with set
+
+    /// Set the quotation used to compute the implementation of gets of this property.
+    member GetterCode           : (Quotations.Expr list -> Quotations.Expr) with set
+
+    /// Set the function used to compute the implementation of gets of this property.
+    member GetterCodeInternal : (Quotations.Expr[] -> Quotations.Expr) with get,set
+
+    /// Set the function used to compute the implementation of sets of this property.
+    member SetterCode           : (Quotations.Expr list -> Quotations.Expr) with set
+
+    /// Set the function used to compute the implementation of sets of this property.
+    member SetterCodeInternal : (Quotations.Expr[] -> Quotations.Expr) with get,set
+
+    /// Add definition location information to the provided type definition.
+    member AddDefinitionLocation : line:int * column:int * filePath:string -> unit
+
+
+#if TPEMIT_INTERNAL_AND_MINIMAL_FOR_TYPE_CONTAINERS
+#else
+/// Represents an erased provided property.
+type ProvidedLiteralField =
+    inherit System.Reflection.FieldInfo
+
+    /// Create a new provided type. It is not initially associated with any specific provided type definition.
+    new  : fieldName: string * fieldType: Type * literalValue: obj -> ProvidedLiteralField
+
+    /// Add XML documentation information to this provided constructor
+    member AddXmlDoc            : xmlDoc: string -> unit    
+
+    /// Add XML documentation information to this provided constructor, where the computation of the documentation is delayed until necessary
+    member AddXmlDocDelayed   : xmlDocFunction: (unit -> string) -> unit   
+    
+    /// Add XML documentation information to this provided constructor, where the computation of the documentation is delayed until necessary
+    /// The documentation is re-computed  every time it is required.
+    member AddXmlDocComputed   : xmlDocFunction: (unit -> string) -> unit   
+
+    /// Add definition location information to the provided type definition.
+    member AddDefinitionLocation : line:int * column:int * filePath:string -> unit
+
+
+/// Represents an erased provided property.
+[<Class>]
+type ProvidedMeasureBuilder =
+    
+    /// The ProvidedMeasureBuilder for building measures.
+    static member Default : ProvidedMeasureBuilder
+
+    /// e.g. 1
+    member One : System.Type
+    /// e.g. m * kg
+    member Product : measure1: System.Type * measure1: System.Type  -> System.Type
+    /// e.g. 1 / kg
+    member Inverse : denominator: System.Type -> System.Type
+
+    /// e.g. kg / m
+    member Ratio : numerator: System.Type * denominator: System.Type -> System.Type
+    
+    /// e.g. m * m 
+    member Square : ``measure``: System.Type -> System.Type
+    
+    /// the SI unit from the F# core library, where the string is in capitals and US spelling, e.g. Meter
+    member SI : string -> System.Type
+    
+    /// e.g. float<kg>, Vector<int, kg>
+    member AnnotateType : basic: System.Type * argument: System.Type list -> System.Type
+
+#endif //TPEMIT_INTERNAL_AND_MINIMAL_FOR_TYPE_CONTAINERS
+
+/// Represents an erased provided parameter
+#if TPEMIT_INTERNAL_AND_MINIMAL_FOR_TYPE_CONTAINERS
+type internal ProvidedStaticParameter =
+#else
+type ProvidedStaticParameter =
+#endif
+    inherit System.Reflection.ParameterInfo
+    new : parameterName: string * parameterType:Type * ?parameterDefaultValue:obj -> ProvidedStaticParameter
+
+/// Represents an erased provided type definition.
+#if TPEMIT_INTERNAL_AND_MINIMAL_FOR_TYPE_CONTAINERS
+type internal ProvidedTypeDefinition =
+#else
+type ProvidedTypeDefinition =
+#endif
+    inherit System.Type
+
+    /// Create a new provided type definition in a namespace. 
+    new : assembly: Assembly * namespaceName: string * className: string * baseType: Type option -> ProvidedTypeDefinition
+
+    /// Create a new provided type definition, to be located as a nested type in some type definition.
+    new : className : string * baseType: Type option -> ProvidedTypeDefinition
+
+    /// Add the given type as an implemented interface.
+    member AddInterfaceImplementation : interfaceType: Type -> unit    
+
+    /// Specifies that the given method body implements the given method declaration.
+    member DefineMethodOverride : methodInfoBody: ProvidedMethod * methodInfoDeclaration: MethodInfo -> unit
+
+    /// Add XML documentation information to this provided constructor
+    member AddXmlDoc             : xmlDoc: string -> unit    
+
+    /// Set the base type
+    member SetBaseType             : Type -> unit    
+
+    /// Add XML documentation information to this provided constructor, where the computation of the documentation is delayed until necessary.
+    /// The documentation is only computed once.
+    member AddXmlDocDelayed   : xmlDocFunction: (unit -> string) -> unit   
+    
+    /// Add XML documentation information to this provided constructor, where the computation of the documentation is delayed until necessary
+    /// The documentation is re-computed  every time it is required.
+    member AddXmlDocComputed   : xmlDocFunction: (unit -> string) -> unit   
+    
+    /// Set the attributes on the provided type. This fully replaces the default TypeAttributes.
+    member SetAttributes        : System.Reflection.TypeAttributes -> unit
+    
+    /// Add a method, property, nested type or other member to a ProvidedTypeDefinition
+    member AddMember         : memberInfo:MemberInfo      -> unit  
+    /// Add a set of members to a ProvidedTypeDefinition
+    member AddMembers        : memberInfos:list<#MemberInfo> -> unit
+
+    /// Add a member to a ProvidedTypeDefinition, delaying computation of the members until required by the compilation context.
+    member AddMemberDelayed  : memberFunction:(unit -> #MemberInfo)      -> unit
+
+    /// Add a set of members to a ProvidedTypeDefinition, delaying computation of the members until required by the compilation context.
+    member AddMembersDelayed : (unit -> list<#MemberInfo>) -> unit    
+    
+    /// Add the types of the generated assembly as generative types, where types in namespaces get hierarchically positioned as nested types.
+    member AddAssemblyTypesAsNestedTypesDelayed : assemblyFunction:(unit -> System.Reflection.Assembly) -> unit
+
+    // Parametric types
+    member DefineStaticParameters     : parameters: ProvidedStaticParameter list * instantiationFunction: (string -> obj[] -> ProvidedTypeDefinition) -> unit
+
+    /// Add definition location information to the provided type definition.
+    member AddDefinitionLocation : line:int * column:int * filePath:string -> unit
+
+    /// Suppress System.Object entries in intellisense menus in instances of this provided type 
+    member HideObjectMethods  : bool with set
+
+    /// Emit the given provided type definition and its nested type definitions into an assembly 
+    /// and adjust the 'Assembly' property of all provided type definitions to return that
+    /// assembly.
+    ///
+    /// The assembly is only emitted when the Assembly property on the root type is accessed for the first time.
+    /// The host F# compiler does this when processing a generative type declaration for the type.
+    member ConvertToGenerated : assemblyFileName: string  * ?reportAssembly: (Assembly * byte[] -> unit) -> unit
+
+    /// Register that a given file is a provided generated assembly
+    static member RegisterGenerated : fileName:string -> Assembly
+
+    /// Get or set a flag indicating if the ProvidedTypeDefinition is erased
+    member IsErased : bool  with get,set
+
+    /// Get or set a flag indicating if the ProvidedTypeDefinition has type-relocation suppressed
+    [<Experimental("SuppressRelocation is a workaround and likely to be removed")>]
+    member SuppressRelocation : bool  with get,set
+
+#if PROVIDER_TRANSFORMATIONS
+[<Sealed;Class;AbstractClass>]
+type ProviderTransformations = 
+    static member FilterTypes : types: Type list * ?methodFilter : (MethodInfo -> bool) * ?eventFilter : (EventInfo -> bool) * ?propertyFilter : (PropertyInfo -> bool) * ?constructorFilter : (ConstructorInfo -> bool) * ?fieldFilter : (FieldInfo -> bool) * ?baseTypeTransform : (Type -> Type option) -> Type list
+#endif
+
+#if TPEMIT_INTERNAL_AND_MINIMAL_FOR_TYPE_CONTAINERS
+#else
+type TypeProviderForNamespaces =
+/// A base type providing default implementations of type provider functionality when all provided types are of type ProvidedTypeDefinition
+// A TypeProvider boiler plate type.
+// 1. Inherit supplying the "providedNamespaces"
+// 2. Add [<Microsoft.FSharp.Core.CompilerServices.TypeProvider>] to type.
+// 3. Add [<assembly:TypeProviderAssembly>] do() to assembly.
+
+    /// Initializes a type provider to provide the types in the given namespace.
+    new : namespaceName:string * types: ProvidedTypeDefinition list -> TypeProviderForNamespaces
+
+    /// Initializes a type provider 
+    new : unit -> TypeProviderForNamespaces
+
+    /// Add a namespace of provided types.
+    member AddNamespace : namespaceName:string * types: ProvidedTypeDefinition list -> unit
+
+    /// Invalidate the information provided by the provider
+    member Invalidate : unit -> unit
+
+    interface ITypeProvider
+#endif
\ No newline at end of file
diff --git a/vsintegration/src/unittests/Resources.MockTypeProviders/EditorHideMethodsAttribute/ArtificalEventInfo.cs b/vsintegration/src/unittests/Resources.MockTypeProviders/EditorHideMethodsAttribute/ArtificalEventInfo.cs
new file mode 100644
index 0000000..5a7fd0c
--- /dev/null
+++ b/vsintegration/src/unittests/Resources.MockTypeProviders/EditorHideMethodsAttribute/ArtificalEventInfo.cs
@@ -0,0 +1,130 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Reflection;
+using Microsoft.FSharp.Core.CompilerServices;
+
+namespace TypeProviderInCSharp
+{
+    class ArtificalEventInfo : EventInfo
+    {
+        string _Name;
+        Type _DeclaringType;
+        Type _EventHandleType;
+        MethodInfo _AddMethod;
+        MethodInfo _RemoveMethod;
+
+        public ArtificalEventInfo(string Name, Type DeclaringType, Type EventHandleType)
+        {
+            _Name = Name;
+            _DeclaringType = DeclaringType;
+            _EventHandleType = EventHandleType;
+
+            _AddMethod = new ArtificialMethodInfo("add_" + _Name, _DeclaringType, typeof(void), MethodAttributes.FamANDAssem | MethodAttributes.Family | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.Public);
+            _RemoveMethod = new ArtificialMethodInfo("remove_" + _Name, _DeclaringType, typeof(void), MethodAttributes.FamANDAssem | MethodAttributes.Family | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.Public);
+        }
+
+        // This one is invoked
+        public override Type EventHandlerType
+        {
+            get
+            {
+                
+                return _EventHandleType;
+            }
+        }
+
+        public override string Name
+        {
+            get 
+            { 
+                
+                return _Name;
+            }
+        }
+
+        public override Type DeclaringType
+        {
+            get
+            {
+                
+                return _DeclaringType;
+            }
+        }
+
+        // This one is needed
+        public override MethodInfo GetAddMethod(bool nonPublic)
+        {
+            
+            Debug.Assert(!nonPublic, "GetAddMethod() was called with nonPublic=true");
+            return _AddMethod;
+        }
+
+        // This one is needed
+        public override MethodInfo GetRemoveMethod(bool nonPublic)
+        {
+            
+            Debug.Assert(!nonPublic, "GetRemoveMethod() was called with nonPublic=true");
+            return _RemoveMethod;
+        }
+
+        public override object[] GetCustomAttributes(Type attributeType, bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        public override EventAttributes Attributes
+        {
+            get
+            {
+                
+                return EventAttributes.None;
+            }
+        }
+
+        public override MethodInfo GetRaiseMethod(bool nonPublic)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override object[] GetCustomAttributes(bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        public override bool IsDefined(Type attributeType, bool inherit)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override Type ReflectedType
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override IList<CustomAttributeData> GetCustomAttributesData()
+        {
+            var attrs = new List<CustomAttributeData>();
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderXmlDocAttribute(string.Format("This is a synthetic *event* created by me for {0}.{1}", this._DeclaringType.Namespace, this._DeclaringType.Name))));
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderDefinitionLocationAttribute() { Column = 21, FilePath = "File.fs", Line = 3 }));
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderEditorHideMethodsAttribute()));
+            return attrs;
+        }
+
+    }
+}
diff --git a/vsintegration/src/unittests/Resources.MockTypeProviders/EditorHideMethodsAttribute/ArtificialConstructorInfo.cs b/vsintegration/src/unittests/Resources.MockTypeProviders/EditorHideMethodsAttribute/ArtificialConstructorInfo.cs
new file mode 100644
index 0000000..da70fb1
--- /dev/null
+++ b/vsintegration/src/unittests/Resources.MockTypeProviders/EditorHideMethodsAttribute/ArtificialConstructorInfo.cs
@@ -0,0 +1,135 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Reflection;
+using Microsoft.FSharp.Core.CompilerServices;
+
+namespace TypeProviderInCSharp
+{
+    class ArtificialConstructorInfo : ConstructorInfo
+    {
+        Type _DeclaringType;
+        ParameterInfo[] _ParameterInfo;
+
+        public ArtificialConstructorInfo(Type DeclaringType, ParameterInfo[] ParamInfo)
+        {
+            _DeclaringType = DeclaringType;
+            _ParameterInfo = ParamInfo;
+        }
+
+        public override Type DeclaringType
+        {
+            get
+            {
+                
+                return _DeclaringType;
+            }
+        }
+
+        // This one is invoked
+        public override ParameterInfo[] GetParameters()
+        {
+            
+            return _ParameterInfo;
+        }
+
+        // This one is indeed invoked
+        // I believe we should always return ".ctor"
+        public override string Name
+        {
+            get
+            {
+                
+                return ".ctor";
+            }
+        }
+
+        // Does it matter what we return here?
+        // This property is definitely checked by the compiler in code like this:
+        // let _ = new N.T()
+        // I copied the attribute set from the .ctor of System.DateTime - the documentation on MSDN assumes that one is already familiar with
+        // what they mean (=totally useless, as often happens)
+        public override MethodAttributes Attributes
+        {
+            get
+            {
+                
+                return MethodAttributes.FamANDAssem | MethodAttributes.Family | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName;
+            }
+        }
+
+        public override object[] GetCustomAttributes(Type attributeType, bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        public override object Invoke(BindingFlags invokeAttr, Binder binder, object[] parameters, System.Globalization.CultureInfo culture)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override MethodImplAttributes GetMethodImplementationFlags()
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override object Invoke(object obj, BindingFlags invokeAttr, Binder binder, object[] parameters, System.Globalization.CultureInfo culture)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override RuntimeMethodHandle MethodHandle
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override object[] GetCustomAttributes(bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        public override bool IsDefined(Type attributeType, bool inherit)
+        {
+           
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override Type ReflectedType
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override IList<CustomAttributeData> GetCustomAttributesData()
+        {
+            var attrs = new List<CustomAttributeData>();
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderXmlDocAttribute(string.Format("This is a synthetic .ctor created by me for {0}.{1}", this._DeclaringType.Namespace, this._DeclaringType.Name))));
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderDefinitionLocationAttribute() { Column = 21, FilePath = "File.fs", Line = 3 }));
+            //attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderEditorHideMethodsAttribute()));
+            return attrs;
+        }
+
+    }
+}
diff --git a/vsintegration/src/unittests/Resources.MockTypeProviders/EditorHideMethodsAttribute/ArtificialMethodInfo.cs b/vsintegration/src/unittests/Resources.MockTypeProviders/EditorHideMethodsAttribute/ArtificialMethodInfo.cs
new file mode 100644
index 0000000..337af50
--- /dev/null
+++ b/vsintegration/src/unittests/Resources.MockTypeProviders/EditorHideMethodsAttribute/ArtificialMethodInfo.cs
@@ -0,0 +1,168 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Reflection;
+using Microsoft.FSharp.Core.CompilerServices;
+
+namespace TypeProviderInCSharp
+{
+    class ArtificialMethodInfo : MethodInfo
+    {
+        string _Name;
+        Type _DeclaringType;
+        Type _ReturnType;
+        MethodAttributes _MethodAttributes;
+
+        public ArtificialMethodInfo(string Name, Type DeclaringType, Type ReturnType, MethodAttributes MethodAttributes)
+        {
+            _Name = Name;
+            _DeclaringType = DeclaringType;
+            _ReturnType = ReturnType;
+            _MethodAttributes = MethodAttributes;
+        }
+
+        public override string Name
+        {
+            get 
+            { 
+                
+                return _Name;
+            }
+        }
+
+        public override Type DeclaringType
+        {
+            get
+            {
+                
+                return _DeclaringType;
+            }
+        }
+
+        // Make the method Public and Static - 
+        // TODO: should be configurable in the ctor...
+        public override MethodAttributes Attributes
+        {
+            get
+            {
+                
+                return _MethodAttributes;
+            }
+        }
+
+        // No params
+        // TODO: should be configurable in the ctor...
+        public override ParameterInfo[] GetParameters()
+        {
+            
+            return new ParameterInfo[] {  };
+        }
+
+        public override ParameterInfo ReturnParameter
+        {
+            get
+            {
+                //
+                //var retvalpi = new ArtificialParamInfo(typeof(List<>), true);
+                //return retvalpi;
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+
+            }
+        }
+
+        public override Type ReturnType
+        {
+            get
+            {
+                
+                return _ReturnType;
+            }
+        }
+
+        public override MethodInfo GetBaseDefinition()
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override ICustomAttributeProvider ReturnTypeCustomAttributes
+        {
+            get 
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override MethodImplAttributes GetMethodImplementationFlags()
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override object Invoke(object obj, BindingFlags invokeAttr, Binder binder, object[] parameters, System.Globalization.CultureInfo culture)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override RuntimeMethodHandle MethodHandle
+        {
+            get 
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override object[] GetCustomAttributes(Type attributeType, bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        public override object[] GetCustomAttributes(bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        public override bool IsDefined(Type attributeType, bool inherit)
+        {
+            
+            Debug.Assert(false, "NYI"); 
+            throw new NotImplementedException();
+        }
+
+        public override Type ReflectedType
+        {
+            get 
+            { 
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override IList<CustomAttributeData> GetCustomAttributesData()
+        {
+            var attrs = new List<CustomAttributeData>();
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderXmlDocAttribute("This is a synthetic *method* created by me!!")));
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderDefinitionLocationAttribute() { Column = 21, FilePath = "File.fs", Line = 3 }));
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderEditorHideMethodsAttribute()));
+            return attrs;
+        }
+
+    }
+}
diff --git a/vsintegration/src/unittests/Resources.MockTypeProviders/EditorHideMethodsAttribute/ArtificialParamInfo.cs b/vsintegration/src/unittests/Resources.MockTypeProviders/EditorHideMethodsAttribute/ArtificialParamInfo.cs
new file mode 100644
index 0000000..6624f2d
--- /dev/null
+++ b/vsintegration/src/unittests/Resources.MockTypeProviders/EditorHideMethodsAttribute/ArtificialParamInfo.cs
@@ -0,0 +1,156 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Reflection;
+using Microsoft.FSharp.Core.CompilerServices;
+
+namespace TypeProviderInCSharp
+{
+    public class ArtificialParamInfo : ParameterInfo
+    {
+        Type _type;
+        bool _isRetVal;
+
+        public ArtificialParamInfo(Type type, bool isRetVal)
+        {
+            _type = type;
+            _isRetVal = IsRetval;
+        }
+
+        // TODO: allow more customizations...
+        public override ParameterAttributes Attributes
+        {
+            get
+            {
+                return _isRetVal ? ParameterAttributes.Retval : ParameterAttributes.None;
+            }
+        }
+
+        public override Type ParameterType
+        {
+            get
+            {
+                return _type;
+            }
+        }
+
+        public override object DefaultValue
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override bool Equals(object obj)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override object[] GetCustomAttributes(bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        public override object[] GetCustomAttributes(Type attributeType, bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        public override int GetHashCode()
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override Type[] GetOptionalCustomModifiers()
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override Type[] GetRequiredCustomModifiers()
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override bool IsDefined(Type attributeType, bool inherit)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override MemberInfo Member
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override int MetadataToken
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override string Name
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override int Position
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override object RawDefaultValue
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override string ToString()
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+    }
+
+}
diff --git a/vsintegration/src/unittests/Resources.MockTypeProviders/EditorHideMethodsAttribute/ArtificialPropertyInfo.cs b/vsintegration/src/unittests/Resources.MockTypeProviders/EditorHideMethodsAttribute/ArtificialPropertyInfo.cs
new file mode 100644
index 0000000..2855992
--- /dev/null
+++ b/vsintegration/src/unittests/Resources.MockTypeProviders/EditorHideMethodsAttribute/ArtificialPropertyInfo.cs
@@ -0,0 +1,180 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Reflection;
+using Microsoft.FSharp.Core.CompilerServices;
+
+namespace TypeProviderInCSharp
+{
+    class ArtificialPropertyInfo : PropertyInfo
+    {
+        string _Name;
+        bool _CanRead;
+        bool _CanWrite;
+        Type _DeclaringType;
+        Type _PropertyType;
+
+        MethodInfo _GetMethod;
+        MethodInfo _SetMethod;
+
+        public ArtificialPropertyInfo(string Name, Type DeclaringType, Type PropertyType, bool CanRead, bool CanWrite)
+        {
+            _Name = Name;
+            _DeclaringType = DeclaringType;
+            _PropertyType = PropertyType;
+            _CanRead = CanRead;
+            _CanWrite = CanWrite;
+
+            if(CanRead)
+                _GetMethod = new ArtificialMethodInfo("get_" + _Name, _DeclaringType, _PropertyType, MethodAttributes.Public | MethodAttributes.Static);
+            if (CanWrite)
+                _SetMethod = new ArtificialMethodInfo("set_" + _Name, _DeclaringType, null /* ?? */, MethodAttributes.Public | MethodAttributes.Static);
+
+        }
+
+        // The name of this property...
+        public override string Name
+        {
+            get
+            {
+                
+                return _Name;
+            }
+        }
+
+        // Needed
+        public override bool CanRead
+        {
+            get
+            {
+                
+                return _CanRead;
+            }
+        }
+
+        // If CanRead is true, this one gets invoked.
+        public override MethodInfo GetGetMethod(bool nonPublic)
+        {
+            
+            Debug.Assert(!nonPublic, "GetGetMethod was invoked with nonPublic=true");
+            return _GetMethod;
+        }
+
+        // Why is this invoked?
+        public override ParameterInfo[] GetIndexParameters()
+        {
+            
+            return new ParameterInfo[] { /* new ArtificialParamInfo(typeof(int), isRetVal: false), new ArtificialParamInfo(typeof(decimal), isRetVal: false) */};
+        }
+
+        // If CanRead is false, this one gets invoked... without checking 'CanWrite' (?)
+        public override MethodInfo GetSetMethod(bool nonPublic)
+        {
+            
+            return _SetMethod;
+        }
+
+        public override bool CanWrite
+        {
+            get
+            {
+                
+                return _CanWrite;
+            }
+        }
+
+        // Interestingly enough, this one seems to be invoked only when I hover over the property in the IDE...
+        public override Type PropertyType
+        {
+            get
+            {
+                
+                return _PropertyType;
+            }
+        }
+
+        // Interestingly enough, this one seems to be invoked only when I hover over the property in the IDE...
+        public override Type DeclaringType
+        {
+            get
+            {
+                
+                return _DeclaringType;
+            }
+        }
+
+        public override object[] GetCustomAttributes(Type attributeType, bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        public override PropertyAttributes Attributes
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override MethodInfo[] GetAccessors(bool nonPublic)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override object GetValue(object obj, BindingFlags invokeAttr, Binder binder, object[] index, System.Globalization.CultureInfo culture)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override void SetValue(object obj, object value, BindingFlags invokeAttr, Binder binder, object[] index, System.Globalization.CultureInfo culture)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override object[] GetCustomAttributes(bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        public override bool IsDefined(Type attributeType, bool inherit)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override Type ReflectedType
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override IList<CustomAttributeData> GetCustomAttributesData()
+        {
+            var attrs = new List<CustomAttributeData>();
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderXmlDocAttribute(string.Format("This is a synthetic *property* created by me for {0}.{1}", this._DeclaringType.Namespace, this._DeclaringType.Name))));
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderDefinitionLocationAttribute() { Column = 21, FilePath = "File.fs", Line = 3 }));
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderEditorHideMethodsAttribute()));
+            return attrs;
+        }
+
+    }
+}
diff --git a/vsintegration/src/unittests/Resources.MockTypeProviders/EditorHideMethodsAttribute/ArtificialType.cs b/vsintegration/src/unittests/Resources.MockTypeProviders/EditorHideMethodsAttribute/ArtificialType.cs
new file mode 100644
index 0000000..25f4623
--- /dev/null
+++ b/vsintegration/src/unittests/Resources.MockTypeProviders/EditorHideMethodsAttribute/ArtificialType.cs
@@ -0,0 +1,769 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Reflection;
+using Microsoft.FSharp.Core.CompilerServices;
+
+namespace TypeProviderInCSharp
+{
+    public class ArtificialType : Type
+    {
+        string _Namespace;
+        string _Name;
+        bool _IsGenericType;
+        bool _IsValueType;  // value type = not class / not interface
+        bool _IsByRef;      // is the value passed by reference?
+        bool _IsEnum;
+        bool _IsPointer;
+
+        Type _BaseType;
+        MethodInfo _Method1;
+        PropertyInfo _Property1;
+        EventInfo _Event1;
+        FieldInfo _Field1;
+        ConstructorInfo _Ctor1;
+
+        public ArtificialType(string @namespace, string name, bool isGenericType, Type basetype, bool isValueType, bool isByRef, bool isEnum, bool IsPointer)
+        {
+            _Name = name;
+            _Namespace = @namespace;
+            _IsGenericType = isGenericType;
+            _BaseType = basetype;
+            _IsValueType = isValueType;
+            _IsByRef = isByRef;
+            _IsEnum = isEnum;
+            _IsPointer = IsPointer;
+            _Method1 = new ArtificialMethodInfo("M", this, typeof(int[]), MethodAttributes.Public | MethodAttributes.Static);
+            _Property1 = new ArtificialPropertyInfo("StaticProp", this, typeof(decimal), true, false);
+            _Event1 = new ArtificalEventInfo("Event1", this, typeof(EventHandler));
+            _Ctor1 = new ArtificialConstructorInfo(this, new ParameterInfo[] {} );  // parameter-less ctor
+        }
+
+        public override System.Reflection.Assembly Assembly
+        {
+            get 
+            { 
+                
+                return Assembly.GetExecutingAssembly();
+            }
+        }
+
+        public override string Name
+        {
+            get 
+            { 
+                
+                return _Name;
+            }
+        }
+
+        public override Type BaseType
+        {
+            get
+            {
+                
+                return _BaseType;
+            }
+        }
+
+        public override string Namespace
+        {
+            get
+            {
+                
+                return _Namespace;
+            }
+        }
+
+        public override string FullName
+        {
+            get
+            { 
+                
+                return string.Format("{0}.{1}", _Namespace, _Name);
+            }
+        }
+
+        public override object[] GetCustomAttributes(Type attributeType, bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        public override object[] GetCustomAttributes(bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        // TODO: what is this?
+        protected override System.Reflection.TypeAttributes GetAttributeFlagsImpl()
+        {
+
+            return TypeAttributes.Class | TypeAttributes.Public | (TypeAttributes)0x40000000; // add the special flag to indicate an erased type, see TypeProviderTypeAttributes
+        }
+
+        // This one seems to be invoked when in IDE, I type something like:
+        // let _ = typeof<N.
+        // In this case => no constructors
+        public override System.Reflection.ConstructorInfo[] GetConstructors(System.Reflection.BindingFlags bindingAttr)
+        {
+            
+            // According to the spec, we should only expect these 4, so we guard against that here!
+            Debug.Assert(bindingAttr == (BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly), "bindingAttr has value not according to the spec!");
+            if (_Ctor1!=null) 
+                return new System.Reflection.ConstructorInfo[] { _Ctor1 };
+            else
+                return new System.Reflection.ConstructorInfo[] { };
+        }
+
+        // When you start typing more interesting things like...
+        // let a = N.T.M()
+        // this one gets invoked...
+        public override System.Reflection.MethodInfo[] GetMethods(System.Reflection.BindingFlags bindingAttr)
+        {
+            
+            // According to the spec, we should only expect these 4, so we guard against that here!
+            Debug.Assert(bindingAttr == (BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly), "bindingAttr has value not according to the spec!");
+            return new[] { _Method1 };
+        }
+
+        // This method is called when in the source file we have something like:
+        // - N.T.StaticProp 
+        // (most likely also when we have an instance prop...)
+        // name -> "StaticProp"
+        protected override System.Reflection.PropertyInfo GetPropertyImpl(string name, System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder binder, Type returnType, Type[] types, System.Reflection.ParameterModifier[] modifiers)
+        {
+            
+            // According to the spec, we should only expect these 4, so we guard against that here!
+            Debug.Assert(bindingAttr == (BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly), "bindingAttr has value not according to the spec!");
+            Debug.Assert(binder == null && returnType == null && types == null && modifiers == null, "One of binder, returnType, types, or modifiers was not null");
+            if (name == _Property1.Name)
+                return _Property1;
+            else
+                return null;
+        }
+
+        // Advertise our property...
+        // I think that is this one returns an empty array => you don't get intellisense/autocomplete in IDE/FSI
+        public override System.Reflection.PropertyInfo[] GetProperties(System.Reflection.BindingFlags bindingAttr)
+        {
+            
+            // According to the spec, we should only expect these 4, so we guard against that here!
+            Debug.Assert(bindingAttr == (BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly), "bindingAttr has value not according to the spec!");
+            return new PropertyInfo[] { _Property1 };
+        }
+
+        // No fields...
+        public override System.Reflection.FieldInfo GetField(string name, System.Reflection.BindingFlags bindingAttr)
+        {
+            
+            // According to the spec, we should only expect these 4, so we guard against that here!
+            Debug.Assert(bindingAttr == (BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly), "bindingAttr has value not according to the spec!");
+            return null;
+        }
+
+        public override System.Reflection.FieldInfo[] GetFields(System.Reflection.BindingFlags bindingAttr)
+        {
+            
+            // According to the spec, we should only expect these 4, so we guard against that here!
+            Debug.Assert(bindingAttr == (BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly), "bindingAttr has value not according to the spec!");
+            return new System.Reflection.FieldInfo[] { };
+        }
+
+        // Events
+        public override System.Reflection.EventInfo GetEvent(string name, System.Reflection.BindingFlags bindingAttr)
+        {
+            
+            // According to the spec, we should only expect these 4, so we guard against that here!
+            Debug.Assert(bindingAttr == (BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly), "bindingAttr has value not according to the spec!");
+            if (_Event1 != null && _Event1.Name == name)
+                return _Event1;
+            else
+                return null;
+        }
+
+        // Events...
+        public override System.Reflection.EventInfo[] GetEvents(System.Reflection.BindingFlags bindingAttr)
+        {
+            
+            return _Event1 != null ? new [] { _Event1 } : new System.Reflection.EventInfo[] { };
+        }
+
+        // TODO: according to the spec, this should not be invoked... instead it seems like it may be invoked...
+        //       ?? I have no idea what this is used for... ??
+        public override Type UnderlyingSystemType
+        {
+            get
+            {
+                
+                return null;
+            }
+        }
+
+        // According to the spec, this should always be 'false'
+        protected override bool IsArrayImpl()
+        {
+            
+            return false;    
+        }
+
+        // No interfaces...
+        public override Type[] GetInterfaces()
+        {
+            
+            return new Type[] { };
+        }
+
+        // No nested type
+        // This method is invoked on the type 'T', e.g.:
+        //    let _ = N.T.M
+        // to figure out if M is a nested type.
+        public override Type GetNestedType(string name, System.Reflection.BindingFlags bindingAttr)
+        {
+            
+            return null;
+        }
+        public override Type[] GetNestedTypes(System.Reflection.BindingFlags bindingAttr)
+        {
+            
+            // According to the spec, we should only expect these 4, so we guard against that here!
+            Debug.Assert(bindingAttr == (BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly), "bindingAttr has value not according to the spec!");
+            return new Type[] { };
+        }
+
+        // This one is invoked when the type has a .ctor 
+        // and the code looks like
+        // let _ = new N.T()
+        // for example.
+        // It was observed that the
+        // TODO: cover both cases!
+        public override bool IsGenericType
+        {
+            get
+            {
+                
+                return _IsGenericType;
+            }
+        }
+
+        // This is invoked if the IsGenericType is true
+        public override Type[] GetGenericArguments()
+        {
+            
+            if (_IsGenericType)
+                return new Type[] { typeof(int), typeof(decimal), typeof(System.Guid) };        // This is currently triggering an ICE...
+            else
+            {
+                Debug.Assert(false, "Why are we here?");
+                throw new NotImplementedException();
+            }
+
+        }
+
+        // This one seems to be invoked when compiling something like
+        // let a = new N.T()
+        // Let's just stay away from generics...
+        public override bool IsGenericTypeDefinition
+        {
+            get
+            {
+                
+                return _IsGenericType;
+            }
+        }
+
+        // This one seems to be invoked when compiling something like
+        // let a = new N.T()
+        // Let's just stay away from generics...
+        public override bool ContainsGenericParameters
+        {
+            get
+            {
+                
+                return _IsGenericType;
+            }
+        }
+
+        // This one seems to be checked when in IDE.
+        // let b = N.T(
+        protected override bool IsValueTypeImpl()
+        {
+            
+            return _IsValueType;
+        }
+
+        // This one seems to be checked when in IDE.
+        // let b = N.T(
+        protected override bool IsByRefImpl()
+        {
+            
+            return _IsByRef;
+        }
+
+        // This one seems to be checked when in IDE.
+        // let b = N.T(
+        public override bool IsEnum
+        {
+            get
+            {
+                
+                return _IsEnum;
+            }
+        }
+
+        // This one seems to be checked when in IDE.
+        // let b = N.T(
+        protected override bool IsPointerImpl()
+        {
+            
+            return _IsPointer;
+        }
+
+        public override string AssemblyQualifiedName
+        {
+            get 
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override Guid GUID
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        protected override System.Reflection.ConstructorInfo GetConstructorImpl(System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder binder, System.Reflection.CallingConventions callConvention, Type[] types, System.Reflection.ParameterModifier[] modifiers)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override Type GetElementType()
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override Type GetInterface(string name, bool ignoreCase)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override System.Reflection.MemberInfo[] GetMembers(System.Reflection.BindingFlags bindingAttr)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        protected override System.Reflection.MethodInfo GetMethodImpl(string name, System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder binder, System.Reflection.CallingConventions callConvention, Type[] types, System.Reflection.ParameterModifier[] modifiers)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        protected override bool HasElementTypeImpl()
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override object InvokeMember(string name, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, object target, object[] args, System.Reflection.ParameterModifier[] modifiers, System.Globalization.CultureInfo culture, string[] namedParameters)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        protected override bool IsCOMObjectImpl()
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        protected override bool IsPrimitiveImpl()
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override System.Reflection.Module Module
+        {
+            get {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override bool IsDefined(Type attributeType, bool inherit)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override MethodBase DeclaringMethod
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.DeclaringMethod;
+            }
+        }
+
+        // This one is invoked by the F# compiler!
+        public override Type DeclaringType
+        {
+            get
+            {
+                
+                return null; // base.DeclaringType;
+            }
+        }
+
+        public override Type[] FindInterfaces(TypeFilter filter, object filterCriteria)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.FindInterfaces(filter, filterCriteria);
+        }
+
+        public override MemberInfo[] FindMembers(MemberTypes memberType, BindingFlags bindingAttr, MemberFilter filter, object filterCriteria)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.FindMembers(memberType, bindingAttr, filter, filterCriteria);
+        }
+
+        public override GenericParameterAttributes GenericParameterAttributes
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.GenericParameterAttributes;
+            }
+        }
+
+        public override int GenericParameterPosition
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.GenericParameterPosition;
+            }
+        }
+
+        public override int GetArrayRank()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetArrayRank();
+        }
+
+        public override MemberInfo[] GetDefaultMembers()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetDefaultMembers();
+        }
+
+        public override string GetEnumName(object value)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetEnumName(value);
+        }
+
+        public override string[] GetEnumNames()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetEnumNames();
+        }
+
+        public override Type GetEnumUnderlyingType()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetEnumUnderlyingType();
+        }
+
+        public override Array GetEnumValues()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetEnumValues();
+        }
+
+        public override EventInfo[] GetEvents()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetEvents();
+        }
+
+        public override Type[] GetGenericParameterConstraints()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetGenericParameterConstraints();
+        }
+
+        public override Type GetGenericTypeDefinition()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetGenericTypeDefinition();
+        }
+
+        public override InterfaceMapping GetInterfaceMap(Type interfaceType)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetInterfaceMap(interfaceType);
+        }
+
+        public override MemberInfo[] GetMember(string name, BindingFlags bindingAttr)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetMember(name, bindingAttr);
+        }
+
+        public override MemberInfo[] GetMember(string name, MemberTypes type, BindingFlags bindingAttr)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetMember(name, type, bindingAttr);
+        }
+
+        protected override TypeCode GetTypeCodeImpl()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetTypeCodeImpl();
+        }
+
+        public override bool IsAssignableFrom(Type c)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.IsAssignableFrom(c);
+        }
+
+        protected override bool IsContextfulImpl()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.IsContextfulImpl();
+        }
+
+        public override bool IsEnumDefined(object value)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.IsEnumDefined(value);
+        }
+
+        public override bool IsEquivalentTo(Type other)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.IsEquivalentTo(other);
+        }
+
+        public override bool IsGenericParameter
+        {
+            get
+            {
+                return _IsGenericType;
+            }
+        }
+
+        public override bool IsInstanceOfType(object o)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.IsInstanceOfType(o);
+        }
+
+        protected override bool IsMarshalByRefImpl()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.IsMarshalByRefImpl();
+        }
+
+        public override bool IsSecurityCritical
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.IsSecurityCritical;
+            }
+        }
+
+        public override bool IsSecuritySafeCritical
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.IsSecuritySafeCritical;
+            }
+        }
+
+        public override bool IsSecurityTransparent
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.IsSecurityTransparent;
+            }
+        }
+
+        public override bool IsSerializable
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.IsSerializable;
+            }
+        }
+
+        public override bool IsSubclassOf(Type c)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.IsSubclassOf(c);
+        }
+
+        public override Type MakeArrayType()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.MakeArrayType();
+        }
+
+        public override Type MakeArrayType(int rank)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.MakeArrayType(rank);
+        }
+
+        public override Type MakeByRefType()
+        {
+            return base.MakeByRefType();
+        }
+
+        public override Type MakeGenericType(params Type[] typeArguments)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.MakeGenericType(typeArguments);
+        }
+
+        public override Type MakePointerType()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.MakePointerType();
+        }
+
+        public override MemberTypes MemberType
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.MemberType;
+            }
+        }
+
+        public override int MetadataToken
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.MetadataToken;
+            }
+        }
+
+        public override Type ReflectedType
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.ReflectedType;
+            }
+        }
+
+        public override System.Runtime.InteropServices.StructLayoutAttribute StructLayoutAttribute
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.StructLayoutAttribute;
+            }
+        }
+
+        public override RuntimeTypeHandle TypeHandle
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.TypeHandle;
+            }
+        }
+
+        public override string ToString()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.ToString();
+        }
+
+        public override IList<CustomAttributeData> GetCustomAttributesData()
+        {
+            var attrs = new List<CustomAttributeData>();
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderXmlDocAttribute("This is a synthetic type created by me!")));
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderDefinitionLocationAttribute() { Column = 5, FilePath = "File.fs", Line = 3 }));
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderEditorHideMethodsAttribute()));
+            return attrs;
+        }
+
+    }
+
+}
diff --git a/vsintegration/src/unittests/Resources.MockTypeProviders/EditorHideMethodsAttribute/EditorHideMethodsAttribute.csproj b/vsintegration/src/unittests/Resources.MockTypeProviders/EditorHideMethodsAttribute/EditorHideMethodsAttribute.csproj
new file mode 100644
index 0000000..c8c0daa
--- /dev/null
+++ b/vsintegration/src/unittests/Resources.MockTypeProviders/EditorHideMethodsAttribute/EditorHideMethodsAttribute.csproj
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information. -->
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <FSharpSourcesRoot>..\..\..\..\..\src</FSharpSourcesRoot>
+    <ProjectLanguage>CSharp</ProjectLanguage>
+  </PropertyGroup>
+  <Import Project="$(FSharpSourcesRoot)\FSharpSource.settings.targets" />
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{0B9CDEAF-EE8F-45E0-A4E0-34A8ED6DD09E}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AssemblyName>EditorHideMethodsAttribute</AssemblyName>
+    <WarningLevel>4</WarningLevel>
+    <NoWarn>0169;0067</NoWarn>
+    <DefineConstants>DEBUG;TRACE;$(DefineConstants)</DefineConstants>
+    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+    <OutputPath>$(FSharpSourcesRoot)\..\$(Configuration)\$(TargetFramework)\bin\UnitTestsResources\MockTypeProviders</OutputPath>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+    <ProjectReference Include="$(FSharpSourcesRoot)\fsharp\FSharp.Core\FSharp.Core.fsproj">
+      <Project>{DED3BBD7-53F4-428A-8C9F-27968E768605}</Project>
+      <Name>FSharp.Core</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="ArtificalEventInfo.cs" />
+    <Compile Include="ArtificialConstructorInfo.cs" />
+    <Compile Include="ArtificialMethodInfo.cs" />
+    <Compile Include="ArtificialParamInfo.cs" />
+    <Compile Include="ArtificialType.cs" />
+    <Compile Include="ArtificialPropertyInfo.cs" />
+    <Compile Include="TypeProviderInCSharp.cs" />
+    <Compile Include="..\Helpers.cs" />
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+</Project>
diff --git a/vsintegration/src/unittests/Resources.MockTypeProviders/EditorHideMethodsAttribute/TypeProviderInCSharp.cs b/vsintegration/src/unittests/Resources.MockTypeProviders/EditorHideMethodsAttribute/TypeProviderInCSharp.cs
new file mode 100644
index 0000000..e4c569b
--- /dev/null
+++ b/vsintegration/src/unittests/Resources.MockTypeProviders/EditorHideMethodsAttribute/TypeProviderInCSharp.cs
@@ -0,0 +1,150 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Microsoft.FSharp.Core.CompilerServices;
+using Microsoft.FSharp.Quotations;
+using System.Reflection;
+using System.Diagnostics;
+
+[assembly: TypeProviderAssembly()]
+
+namespace TypeProviderInCSharp
+{
+    //namespace N
+    //{
+    //    class S
+    //    {
+    //        public int instanceField;
+    //        public S(int x)
+    //        {
+    //            instanceField = x;
+    //        }
+    //    }
+    //}
+
+    class Namespace1 : IProvidedNamespace
+    {
+        const string _Namespace = "N";
+        const string _Name = "T";
+
+        // Type myType = new myType(typeof(N.S), "Bad.Name", typeof(Action), true);
+        Type myType = new ArtificialType(_Namespace, _Name, false, basetype: typeof(object), isValueType: false, isByRef: false, isEnum: false, IsPointer: false);
+
+        public IProvidedNamespace[] GetNestedNamespaces()
+        {
+
+            return new IProvidedNamespace[] { };
+        }
+
+        public Type[] GetTypes()
+        {
+
+            return new Type[] { myType };
+        }
+
+        public string NamespaceName
+        {
+            get { return _Namespace; }
+        }
+
+        public Type ResolveTypeName(string typeName)
+        {
+
+            if (typeName == _Name)
+            {
+                return myType;
+            }
+            return null;
+        }
+    }
+
+    [TypeProvider()]
+    public class TypeProvider : ITypeProvider
+    {
+        void IDisposable.Dispose()
+        {
+        }
+        private void Param(int staticParam)
+        {
+        }
+
+        public Type ApplyStaticArguments(Type typeWithoutArguments, string[] typeNameWithArguments, object[] staticArguments)
+        {
+            //Console.WriteLine("Hello from ApplyStaticArguments");
+            //var n = new myType(typeof(N.S), "S,\"1\"", typeof(object), false);
+            //return n;
+
+            return null;
+        }
+
+        public FSharpExpr GetInvokerExpression(System.Reflection.MethodBase syntheticMethodBase, FSharpExpr[] parameters)
+        {
+
+            if (syntheticMethodBase is System.Reflection.ConstructorInfo)
+            {
+                var ac = syntheticMethodBase as ArtificialConstructorInfo;
+                if (ac.DeclaringType.FullName == "N.T")
+                {
+                    return FSharpExpr.DefaultValue(ac.DeclaringType.BaseType);
+                }
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+            else if (syntheticMethodBase is System.Reflection.MethodInfo)
+            {
+                var am = syntheticMethodBase as ArtificialMethodInfo;
+                if (am.DeclaringType.FullName == "N.T" && am.Name == "M")
+                {
+                    return FSharpExpr.Lambda(FSharpVar.Global("", typeof(int[])), FSharpExpr.Value<int[]>(new[] { 1, 2, 3 }));
+                }
+                else if (am.DeclaringType.FullName == "N.T" && am.Name == "get_StaticProp")
+                {
+                    return FSharpExpr.Lambda(FSharpVar.Global("", typeof(decimal)), FSharpExpr.Value<decimal>(4.2M));
+                }
+                else if (am.DeclaringType.FullName == "N.T" && am.Name == "add_Event1")
+                {
+                    // Dummy expr... since we do not care about what it really does...
+                    return FSharpExpr.Lambda(FSharpVar.Global("", typeof(int)), FSharpExpr.Value<int>(1));
+                }
+                else if (am.DeclaringType.FullName == "N.T" && am.Name == "remove_Event1")
+                {
+                    // Dummy expr... since we do not care about what it really does...
+                    return FSharpExpr.Lambda(FSharpVar.Global("", typeof(int)), FSharpExpr.Value<int>(1));
+                }
+                else
+                {
+                    Debug.Assert(false, "NYI");
+                    throw new NotImplementedException();
+                }
+            }
+            else
+            {
+                Debug.Assert(false, "GetInvokerExpression() invoked with neither ConstructorInfo nor MethodInfo!");
+                return null;
+            }
+            //Expression<Func<S>> e = () => new S(9);
+            //return e.Body;
+
+            //throw new NotImplementedException();
+        }
+
+        public IProvidedNamespace[] GetNamespaces()
+        {
+
+            return new IProvidedNamespace[] { new Namespace1() };
+        }
+
+        public System.Reflection.ParameterInfo[] GetStaticParameters(Type typeWithoutArguments)
+        {
+
+            // No StaticParams
+            return new ParameterInfo[] { /* new myParameterInfo() */ };
+        }
+
+        public event EventHandler Invalidate;
+        public byte[] GetGeneratedAssemblyContents(Assembly assembly) { throw (new Exception("GetGeneratedAssemblyContents - only erased types were provided!!")); }
+    }
+}
diff --git a/vsintegration/src/unittests/Resources.MockTypeProviders/EmptyAssembly/EmptyAssembly.fs b/vsintegration/src/unittests/Resources.MockTypeProviders/EmptyAssembly/EmptyAssembly.fs
new file mode 100644
index 0000000..8beeade
--- /dev/null
+++ b/vsintegration/src/unittests/Resources.MockTypeProviders/EmptyAssembly/EmptyAssembly.fs
@@ -0,0 +1,10 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+namespace EmptyAssembly
+
+open Microsoft.FSharp.Core.CompilerServices
+
+// The point is to test a warning diagnostic about assemblies with the attribute below but with no type providers defined
+
+[<assembly:TypeProviderAssembly>]
+do()
\ No newline at end of file
diff --git a/vsintegration/src/unittests/Resources.MockTypeProviders/EmptyAssembly/EmptyAssembly.fsproj b/vsintegration/src/unittests/Resources.MockTypeProviders/EmptyAssembly/EmptyAssembly.fsproj
new file mode 100644
index 0000000..64a8e06
--- /dev/null
+++ b/vsintegration/src/unittests/Resources.MockTypeProviders/EmptyAssembly/EmptyAssembly.fsproj
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information. -->
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <FSharpSourcesRoot>..\..\..\..\..\src</FSharpSourcesRoot>
+    <ProjectLanguage>FSharp</ProjectLanguage>
+  </PropertyGroup>
+  <Import Project="$(FSharpSourcesRoot)\FSharpSource.settings.targets" />
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{004982c6-93ea-4e70-b4f0-be7d7219926a}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AssemblyName>EmptyAssembly</AssemblyName>
+    <TargetType>LIBRARY</TargetType>
+    <EnsureThereAreNoUnusedFsSrGenResources>False</EnsureThereAreNoUnusedFsSrGenResources>
+    <NoWarn>58;75</NoWarn>
+    <GenerateDocumentationFile>false</GenerateDocumentationFile>
+    <DefineConstants>DEBUG;TRACE;$(DefineConstants)</DefineConstants>
+    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+    <CustomOutputPath>true</CustomOutputPath>
+    <OutputPath>$(FSharpSourcesRoot)\..\$(Configuration)\$(TargetFramework)\bin\UnitTestsResources\MockTypeProviders</OutputPath>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+    <Reference Include="mscorlib" />
+    <ProjectReference Include="$(FSharpSourcesRoot)\fsharp\FSharp.Core\FSharp.Core.fsproj">
+      <Project>{DED3BBD7-53F4-428A-8C9F-27968E768605}</Project>
+      <Name>FSharp.Core</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <ItemGroup>
+    <FsSrGen Include="$(FSharpSourcesRoot)\fsharp\FSharp.Data.TypeProviders\FSData.txt" >
+      <Link>FSData.txt</Link>
+    </FsSrGen>
+    <Compile Include="EmptyAssembly.fs" />
+  </ItemGroup>
+  <Import Project="$(FSharpSourcesRoot)\FSharpSource.targets" />
+</Project>
\ No newline at end of file
diff --git a/vsintegration/src/unittests/Resources.MockTypeProviders/Helpers.cs b/vsintegration/src/unittests/Resources.MockTypeProviders/Helpers.cs
new file mode 100644
index 0000000..979eb28
--- /dev/null
+++ b/vsintegration/src/unittests/Resources.MockTypeProviders/Helpers.cs
@@ -0,0 +1,58 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Reflection;
+using Microsoft.FSharp.Core.CompilerServices;
+
+namespace TypeProviderInCSharp
+{
+    static class Helpers
+    {
+        internal class TypeProviderCustomAttributeData : CustomAttributeData
+        {
+            protected readonly Attribute _a;
+            public TypeProviderCustomAttributeData(Attribute a)
+            {
+                _a = a;
+            }
+
+            public override ConstructorInfo Constructor
+            {
+                get
+                {
+                    return _a.GetType().GetConstructors()[0];
+                }
+            }
+
+            public override IList<CustomAttributeTypedArgument> ConstructorArguments
+            {
+                get
+                {
+                    if (_a is TypeProviderXmlDocAttribute)
+                        return new List<CustomAttributeTypedArgument>() { new CustomAttributeTypedArgument(typeof(string), ((TypeProviderXmlDocAttribute)_a).CommentText) };
+                    else // if (_a is TypeProviderDefinitionLocationAttribute || _a is TypeProviderEditorHideMethodsAttribute)
+                        return new List<CustomAttributeTypedArgument>();
+                }
+            }
+
+            public override IList<CustomAttributeNamedArgument> NamedArguments
+            {
+                get
+                {
+                    if (_a is TypeProviderDefinitionLocationAttribute)
+                    {
+                        var t = _a.GetType();
+                        return new List<CustomAttributeNamedArgument>() { new CustomAttributeNamedArgument(t.GetProperty("Column"), ((TypeProviderDefinitionLocationAttribute)_a).Column),
+                                                                      new CustomAttributeNamedArgument(t.GetProperty("FilePath"), ((TypeProviderDefinitionLocationAttribute)_a).FilePath),
+                                                                      new CustomAttributeNamedArgument(t.GetProperty("Line"), ((TypeProviderDefinitionLocationAttribute)_a).Line) };
+                    }
+                    else // if (_a is TypeProviderXmlDocAttribute || _a is TypeProviderEditorHideMethodsAttribute)
+                        return new List<CustomAttributeNamedArgument>();
+                }
+            }
+        }
+
+    }
+}
diff --git a/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithAdequateComment/ArtificalEventInfo.cs b/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithAdequateComment/ArtificalEventInfo.cs
new file mode 100644
index 0000000..5a7fd0c
--- /dev/null
+++ b/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithAdequateComment/ArtificalEventInfo.cs
@@ -0,0 +1,130 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Reflection;
+using Microsoft.FSharp.Core.CompilerServices;
+
+namespace TypeProviderInCSharp
+{
+    class ArtificalEventInfo : EventInfo
+    {
+        string _Name;
+        Type _DeclaringType;
+        Type _EventHandleType;
+        MethodInfo _AddMethod;
+        MethodInfo _RemoveMethod;
+
+        public ArtificalEventInfo(string Name, Type DeclaringType, Type EventHandleType)
+        {
+            _Name = Name;
+            _DeclaringType = DeclaringType;
+            _EventHandleType = EventHandleType;
+
+            _AddMethod = new ArtificialMethodInfo("add_" + _Name, _DeclaringType, typeof(void), MethodAttributes.FamANDAssem | MethodAttributes.Family | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.Public);
+            _RemoveMethod = new ArtificialMethodInfo("remove_" + _Name, _DeclaringType, typeof(void), MethodAttributes.FamANDAssem | MethodAttributes.Family | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.Public);
+        }
+
+        // This one is invoked
+        public override Type EventHandlerType
+        {
+            get
+            {
+                
+                return _EventHandleType;
+            }
+        }
+
+        public override string Name
+        {
+            get 
+            { 
+                
+                return _Name;
+            }
+        }
+
+        public override Type DeclaringType
+        {
+            get
+            {
+                
+                return _DeclaringType;
+            }
+        }
+
+        // This one is needed
+        public override MethodInfo GetAddMethod(bool nonPublic)
+        {
+            
+            Debug.Assert(!nonPublic, "GetAddMethod() was called with nonPublic=true");
+            return _AddMethod;
+        }
+
+        // This one is needed
+        public override MethodInfo GetRemoveMethod(bool nonPublic)
+        {
+            
+            Debug.Assert(!nonPublic, "GetRemoveMethod() was called with nonPublic=true");
+            return _RemoveMethod;
+        }
+
+        public override object[] GetCustomAttributes(Type attributeType, bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        public override EventAttributes Attributes
+        {
+            get
+            {
+                
+                return EventAttributes.None;
+            }
+        }
+
+        public override MethodInfo GetRaiseMethod(bool nonPublic)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override object[] GetCustomAttributes(bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        public override bool IsDefined(Type attributeType, bool inherit)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override Type ReflectedType
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override IList<CustomAttributeData> GetCustomAttributesData()
+        {
+            var attrs = new List<CustomAttributeData>();
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderXmlDocAttribute(string.Format("This is a synthetic *event* created by me for {0}.{1}", this._DeclaringType.Namespace, this._DeclaringType.Name))));
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderDefinitionLocationAttribute() { Column = 21, FilePath = "File.fs", Line = 3 }));
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderEditorHideMethodsAttribute()));
+            return attrs;
+        }
+
+    }
+}
diff --git a/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithAdequateComment/ArtificialConstructorInfo.cs b/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithAdequateComment/ArtificialConstructorInfo.cs
new file mode 100644
index 0000000..5899d39
--- /dev/null
+++ b/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithAdequateComment/ArtificialConstructorInfo.cs
@@ -0,0 +1,135 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Reflection;
+using Microsoft.FSharp.Core.CompilerServices;
+
+namespace TypeProviderInCSharp
+{
+    class ArtificialConstructorInfo : ConstructorInfo
+    {
+        Type _DeclaringType;
+        ParameterInfo[] _ParameterInfo;
+
+        public ArtificialConstructorInfo(Type DeclaringType, ParameterInfo[] ParamInfo)
+        {
+            _DeclaringType = DeclaringType;
+            _ParameterInfo = ParamInfo;
+        }
+
+        public override Type DeclaringType
+        {
+            get
+            {
+                
+                return _DeclaringType;
+            }
+        }
+
+        // This one is invoked
+        public override ParameterInfo[] GetParameters()
+        {
+            
+            return _ParameterInfo;
+        }
+
+        // This one is indeed invoked
+        // I believe we should always return ".ctor"
+        public override string Name
+        {
+            get
+            {
+                
+                return ".ctor";
+            }
+        }
+
+        // Does it matter what we return here?
+        // This property is definitely checked by the compiler in code like this:
+        // let _ = new N.T()
+        // I copied the attribute set from the .ctor of System.DateTime - the documentation on MSDN assumes that one is already familiar with
+        // what they mean (=totally useless, as often happens)
+        public override MethodAttributes Attributes
+        {
+            get
+            {
+                
+                return MethodAttributes.FamANDAssem | MethodAttributes.Family | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName;
+            }
+        }
+
+        public override object[] GetCustomAttributes(Type attributeType, bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        public override object Invoke(BindingFlags invokeAttr, Binder binder, object[] parameters, System.Globalization.CultureInfo culture)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override MethodImplAttributes GetMethodImplementationFlags()
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override object Invoke(object obj, BindingFlags invokeAttr, Binder binder, object[] parameters, System.Globalization.CultureInfo culture)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override RuntimeMethodHandle MethodHandle
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override object[] GetCustomAttributes(bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        public override bool IsDefined(Type attributeType, bool inherit)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override Type ReflectedType
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override IList<CustomAttributeData> GetCustomAttributesData()
+        {
+            var attrs = new List<CustomAttributeData>();
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderXmlDocAttribute(string.Format("This is a synthetic .ctor created by me for {0}.{1}", this._DeclaringType.Namespace, this._DeclaringType.Name))));
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderDefinitionLocationAttribute() { Column = 21, FilePath = "File.fs", Line = 3 }));
+            // attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderEditorHideMethodsAttribute()));
+            return attrs;
+        }
+
+    }
+}
diff --git a/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithAdequateComment/ArtificialMethodInfo.cs b/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithAdequateComment/ArtificialMethodInfo.cs
new file mode 100644
index 0000000..337af50
--- /dev/null
+++ b/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithAdequateComment/ArtificialMethodInfo.cs
@@ -0,0 +1,168 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Reflection;
+using Microsoft.FSharp.Core.CompilerServices;
+
+namespace TypeProviderInCSharp
+{
+    class ArtificialMethodInfo : MethodInfo
+    {
+        string _Name;
+        Type _DeclaringType;
+        Type _ReturnType;
+        MethodAttributes _MethodAttributes;
+
+        public ArtificialMethodInfo(string Name, Type DeclaringType, Type ReturnType, MethodAttributes MethodAttributes)
+        {
+            _Name = Name;
+            _DeclaringType = DeclaringType;
+            _ReturnType = ReturnType;
+            _MethodAttributes = MethodAttributes;
+        }
+
+        public override string Name
+        {
+            get 
+            { 
+                
+                return _Name;
+            }
+        }
+
+        public override Type DeclaringType
+        {
+            get
+            {
+                
+                return _DeclaringType;
+            }
+        }
+
+        // Make the method Public and Static - 
+        // TODO: should be configurable in the ctor...
+        public override MethodAttributes Attributes
+        {
+            get
+            {
+                
+                return _MethodAttributes;
+            }
+        }
+
+        // No params
+        // TODO: should be configurable in the ctor...
+        public override ParameterInfo[] GetParameters()
+        {
+            
+            return new ParameterInfo[] {  };
+        }
+
+        public override ParameterInfo ReturnParameter
+        {
+            get
+            {
+                //
+                //var retvalpi = new ArtificialParamInfo(typeof(List<>), true);
+                //return retvalpi;
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+
+            }
+        }
+
+        public override Type ReturnType
+        {
+            get
+            {
+                
+                return _ReturnType;
+            }
+        }
+
+        public override MethodInfo GetBaseDefinition()
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override ICustomAttributeProvider ReturnTypeCustomAttributes
+        {
+            get 
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override MethodImplAttributes GetMethodImplementationFlags()
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override object Invoke(object obj, BindingFlags invokeAttr, Binder binder, object[] parameters, System.Globalization.CultureInfo culture)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override RuntimeMethodHandle MethodHandle
+        {
+            get 
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override object[] GetCustomAttributes(Type attributeType, bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        public override object[] GetCustomAttributes(bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        public override bool IsDefined(Type attributeType, bool inherit)
+        {
+            
+            Debug.Assert(false, "NYI"); 
+            throw new NotImplementedException();
+        }
+
+        public override Type ReflectedType
+        {
+            get 
+            { 
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override IList<CustomAttributeData> GetCustomAttributesData()
+        {
+            var attrs = new List<CustomAttributeData>();
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderXmlDocAttribute("This is a synthetic *method* created by me!!")));
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderDefinitionLocationAttribute() { Column = 21, FilePath = "File.fs", Line = 3 }));
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderEditorHideMethodsAttribute()));
+            return attrs;
+        }
+
+    }
+}
diff --git a/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithAdequateComment/ArtificialParamInfo.cs b/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithAdequateComment/ArtificialParamInfo.cs
new file mode 100644
index 0000000..65f58aa
--- /dev/null
+++ b/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithAdequateComment/ArtificialParamInfo.cs
@@ -0,0 +1,157 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Reflection;
+using Microsoft.FSharp.Core.CompilerServices;
+
+namespace TypeProviderInCSharp
+{
+    public class ArtificialParamInfo : ParameterInfo
+    {
+        Type _type;
+        bool _isRetVal;
+
+        public ArtificialParamInfo(Type type, bool isRetVal)
+        {
+            _type = type;
+            _isRetVal = IsRetval;
+        }
+
+        // TODO: allow more customizations...
+        public override ParameterAttributes Attributes
+        {
+            get
+            {
+                return _isRetVal ? ParameterAttributes.Retval : ParameterAttributes.None;
+            }
+        }
+
+        public override Type ParameterType
+        {
+            get
+            {
+                return _type;
+            }
+        }
+
+        public override object DefaultValue
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override bool Equals(object obj)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override object[] GetCustomAttributes(bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        public override object[] GetCustomAttributes(Type attributeType, bool inherit)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override int GetHashCode()
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override Type[] GetOptionalCustomModifiers()
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override Type[] GetRequiredCustomModifiers()
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override bool IsDefined(Type attributeType, bool inherit)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override MemberInfo Member
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override int MetadataToken
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override string Name
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override int Position
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override object RawDefaultValue
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override string ToString()
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+    }
+
+}
diff --git a/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithAdequateComment/ArtificialPropertyInfo.cs b/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithAdequateComment/ArtificialPropertyInfo.cs
new file mode 100644
index 0000000..7928039
--- /dev/null
+++ b/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithAdequateComment/ArtificialPropertyInfo.cs
@@ -0,0 +1,181 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Reflection;
+using Microsoft.FSharp.Core.CompilerServices;
+
+namespace TypeProviderInCSharp
+{
+    class ArtificialPropertyInfo : PropertyInfo
+    {
+        string _Name;
+        bool _CanRead;
+        bool _CanWrite;
+        Type _DeclaringType;
+        Type _PropertyType;
+
+        MethodInfo _GetMethod;
+        MethodInfo _SetMethod;
+
+        public ArtificialPropertyInfo(string Name, Type DeclaringType, Type PropertyType, bool CanRead, bool CanWrite)
+        {
+            _Name = Name;
+            _DeclaringType = DeclaringType;
+            _PropertyType = PropertyType;
+            _CanRead = CanRead;
+            _CanWrite = CanWrite;
+
+            if(CanRead)
+                _GetMethod = new ArtificialMethodInfo("get_" + _Name, _DeclaringType, _PropertyType, MethodAttributes.Public | MethodAttributes.Static);
+            if (CanWrite)
+                _SetMethod = new ArtificialMethodInfo("set_" + _Name, _DeclaringType, null /* ?? */, MethodAttributes.Public | MethodAttributes.Static);
+
+        }
+
+        // The name of this property...
+        public override string Name
+        {
+            get
+            {
+                
+                return _Name;
+            }
+        }
+
+        // Needed
+        public override bool CanRead
+        {
+            get
+            {
+                
+                return _CanRead;
+            }
+        }
+
+        // If CanRead is true, this one gets invoked.
+        public override MethodInfo GetGetMethod(bool nonPublic)
+        {
+            
+            Debug.Assert(!nonPublic, "GetGetMethod was invoked with nonPublic=true");
+            return _GetMethod;
+        }
+
+        // Why is this invoked?
+        public override ParameterInfo[] GetIndexParameters()
+        {
+            
+            return new ParameterInfo[] { /* new ArtificialParamInfo(typeof(int), isRetVal: false), new ArtificialParamInfo(typeof(decimal), isRetVal: false) */};
+        }
+
+        // If CanRead is false, this one gets invoked... without checking 'CanWrite' (?)
+        public override MethodInfo GetSetMethod(bool nonPublic)
+        {
+            
+            return _SetMethod;
+        }
+
+        public override bool CanWrite
+        {
+            get
+            {
+                
+                return _CanWrite;
+            }
+        }
+
+        // Interestingly enough, this one seems to be invoked only when I hover over the property in the IDE...
+        public override Type PropertyType
+        {
+            get
+            {
+                
+                return _PropertyType;
+            }
+        }
+
+        // Interestingly enough, this one seems to be invoked only when I hover over the property in the IDE...
+        public override Type DeclaringType
+        {
+            get
+            {
+                
+                return _DeclaringType;
+            }
+        }
+
+        public override object[] GetCustomAttributes(Type attributeType, bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+
+        public override PropertyAttributes Attributes
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override MethodInfo[] GetAccessors(bool nonPublic)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override object GetValue(object obj, BindingFlags invokeAttr, Binder binder, object[] index, System.Globalization.CultureInfo culture)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override void SetValue(object obj, object value, BindingFlags invokeAttr, Binder binder, object[] index, System.Globalization.CultureInfo culture)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override object[] GetCustomAttributes(bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        public override bool IsDefined(Type attributeType, bool inherit)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override Type ReflectedType
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override IList<CustomAttributeData> GetCustomAttributesData()
+        {
+            var attrs = new List<CustomAttributeData>();
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderXmlDocAttribute(string.Format("This is a synthetic *property* created by me for {0}.{1}", this._DeclaringType.Namespace, this._DeclaringType.Name))));
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderDefinitionLocationAttribute() { Column = 21, FilePath = "File.fs", Line = 3 }));
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderEditorHideMethodsAttribute()));
+            return attrs;
+        }
+
+    }
+}
diff --git a/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithAdequateComment/ArtificialType.cs b/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithAdequateComment/ArtificialType.cs
new file mode 100644
index 0000000..90f5e0c
--- /dev/null
+++ b/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithAdequateComment/ArtificialType.cs
@@ -0,0 +1,768 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Reflection;
+using Microsoft.FSharp.Core.CompilerServices;
+
+namespace TypeProviderInCSharp
+{
+    public class ArtificialType : Type
+    {
+        string _Namespace;
+        string _Name;
+        bool _IsGenericType;
+        bool _IsValueType;  // value type = not class / not interface
+        bool _IsByRef;      // is the value passed by reference?
+        bool _IsEnum;
+        bool _IsPointer;
+
+        Type _BaseType;
+        MethodInfo _Method1;
+        PropertyInfo _Property1;
+        EventInfo _Event1;
+        FieldInfo _Field1;
+        ConstructorInfo _Ctor1;
+
+        public ArtificialType(string @namespace, string name, bool isGenericType, Type basetype, bool isValueType, bool isByRef, bool isEnum, bool IsPointer)
+        {
+            _Name = name;
+            _Namespace = @namespace;
+            _IsGenericType = isGenericType;
+            _BaseType = basetype;
+            _IsValueType = isValueType;
+            _IsByRef = isByRef;
+            _IsEnum = isEnum;
+            _IsPointer = IsPointer;
+            _Method1 = new ArtificialMethodInfo("M", this, typeof(int[]), MethodAttributes.Public | MethodAttributes.Static);
+            _Property1 = new ArtificialPropertyInfo("StaticProp", this, typeof(decimal), true, false);
+            _Event1 = new ArtificalEventInfo("Event1", this, typeof(EventHandler));
+            _Ctor1 = new ArtificialConstructorInfo(this, new ParameterInfo[] {} );  // parameter-less ctor
+        }
+
+        public override System.Reflection.Assembly Assembly
+        {
+            get 
+            { 
+                
+                return Assembly.GetExecutingAssembly();
+            }
+        }
+
+        public override string Name
+        {
+            get 
+            { 
+                
+                return _Name;
+            }
+        }
+
+        public override Type BaseType
+        {
+            get
+            {
+                
+                return _BaseType;
+            }
+        }
+
+        public override string Namespace
+        {
+            get
+            {
+                
+                return _Namespace;
+            }
+        }
+
+        public override string FullName
+        {
+            get
+            { 
+                
+                return string.Format("{0}.{1}", _Namespace, _Name);
+            }
+        }
+
+        public override object[] GetCustomAttributes(Type attributeType, bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        public override object[] GetCustomAttributes(bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        // TODO: what is this?
+        protected override System.Reflection.TypeAttributes GetAttributeFlagsImpl()
+        {
+
+            return TypeAttributes.Class | TypeAttributes.Public | (TypeAttributes)0x40000000; // add the special flag to indicate an erased type, see TypeProviderTypeAttributes
+        }
+
+        // This one seems to be invoked when in IDE, I type something like:
+        // let _ = typeof<N.
+        // In this case => no constructors
+        public override System.Reflection.ConstructorInfo[] GetConstructors(System.Reflection.BindingFlags bindingAttr)
+        {
+            
+            // According to the spec, we should only expect these 4, so we guard against that here!
+            Debug.Assert(bindingAttr == (BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly), "bindingAttr has value not according to the spec!");
+            if (_Ctor1!=null) 
+                return new System.Reflection.ConstructorInfo[] { _Ctor1 };
+            else
+                return new System.Reflection.ConstructorInfo[] { };
+        }
+
+        // When you start typing more interesting things like...
+        // let a = N.T.M()
+        // this one gets invoked...
+        public override System.Reflection.MethodInfo[] GetMethods(System.Reflection.BindingFlags bindingAttr)
+        {
+            
+            // According to the spec, we should only expect these 4, so we guard against that here!
+            Debug.Assert(bindingAttr == (BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly), "bindingAttr has value not according to the spec!");
+            return new[] { _Method1 };
+        }
+
+        // This method is called when in the source file we have something like:
+        // - N.T.StaticProp 
+        // (most likely also when we have an instance prop...)
+        // name -> "StaticProp"
+        protected override System.Reflection.PropertyInfo GetPropertyImpl(string name, System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder binder, Type returnType, Type[] types, System.Reflection.ParameterModifier[] modifiers)
+        {
+            
+            // According to the spec, we should only expect these 4, so we guard against that here!
+            Debug.Assert(bindingAttr == (BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly), "bindingAttr has value not according to the spec!");
+            Debug.Assert(binder == null && returnType == null && types == null && modifiers == null, "One of binder, returnType, types, or modifiers was not null");
+            if (name == _Property1.Name)
+                return _Property1;
+            else
+                return null;
+        }
+
+        // Advertise our property...
+        // I think that is this one returns an empty array => you don't get intellisense/autocomplete in IDE/FSI
+        public override System.Reflection.PropertyInfo[] GetProperties(System.Reflection.BindingFlags bindingAttr)
+        {
+            
+            // According to the spec, we should only expect these 4, so we guard against that here!
+            Debug.Assert(bindingAttr == (BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly), "bindingAttr has value not according to the spec!");
+            return new PropertyInfo[] { _Property1 };
+        }
+
+        // No fields...
+        public override System.Reflection.FieldInfo GetField(string name, System.Reflection.BindingFlags bindingAttr)
+        {
+            
+            // According to the spec, we should only expect these 4, so we guard against that here!
+            Debug.Assert(bindingAttr == (BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly), "bindingAttr has value not according to the spec!");
+            return null;
+        }
+
+        public override System.Reflection.FieldInfo[] GetFields(System.Reflection.BindingFlags bindingAttr)
+        {
+            
+            // According to the spec, we should only expect these 4, so we guard against that here!
+            Debug.Assert(bindingAttr == (BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly), "bindingAttr has value not according to the spec!");
+            return new System.Reflection.FieldInfo[] { };
+        }
+
+        // Events
+        public override System.Reflection.EventInfo GetEvent(string name, System.Reflection.BindingFlags bindingAttr)
+        {
+            
+            // According to the spec, we should only expect these 4, so we guard against that here!
+            Debug.Assert(bindingAttr == (BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly), "bindingAttr has value not according to the spec!");
+            if (_Event1 != null && _Event1.Name == name)
+                return _Event1;
+            else
+                return null;
+        }
+
+        // Events...
+        public override System.Reflection.EventInfo[] GetEvents(System.Reflection.BindingFlags bindingAttr)
+        {
+            
+            return _Event1 != null ? new [] { _Event1 } : new System.Reflection.EventInfo[] { };
+        }
+
+        // TODO: according to the spec, this should not be invoked... instead it seems like it may be invoked...
+        //       ?? I have no idea what this is used for... ??
+        public override Type UnderlyingSystemType
+        {
+            get
+            {
+                
+                return null;
+            }
+        }
+
+        // According to the spec, this should always be 'false'
+        protected override bool IsArrayImpl()
+        {
+            
+            return false;    
+        }
+
+        // No interfaces...
+        public override Type[] GetInterfaces()
+        {
+            
+            return new Type[] { };
+        }
+
+        // No nested type
+        // This method is invoked on the type 'T', e.g.:
+        //    let _ = N.T.M
+        // to figure out if M is a nested type.
+        public override Type GetNestedType(string name, System.Reflection.BindingFlags bindingAttr)
+        {
+            
+            return null;
+        }
+        public override Type[] GetNestedTypes(System.Reflection.BindingFlags bindingAttr)
+        {
+            
+            // According to the spec, we should only expect these 4, so we guard against that here!
+            Debug.Assert(bindingAttr == (BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly), "bindingAttr has value not according to the spec!");
+            return new Type[] { };
+        }
+
+        // This one is invoked when the type has a .ctor 
+        // and the code looks like
+        // let _ = new N.T()
+        // for example.
+        // It was observed that the
+        // TODO: cover both cases!
+        public override bool IsGenericType
+        {
+            get
+            {
+                
+                return _IsGenericType;
+            }
+        }
+
+        // This is invoked if the IsGenericType is true
+        public override Type[] GetGenericArguments()
+        {
+            
+            if (_IsGenericType)
+                return new Type[] { typeof(int), typeof(decimal), typeof(System.Guid) };        // This is currently triggering an ICE...
+            else
+            {
+                Debug.Assert(false, "Why are we here?");
+                throw new NotImplementedException();
+            }
+
+        }
+
+        // This one seems to be invoked when compiling something like
+        // let a = new N.T()
+        // Let's just stay away from generics...
+        public override bool IsGenericTypeDefinition
+        {
+            get
+            {
+                
+                return _IsGenericType;
+            }
+        }
+
+        // This one seems to be invoked when compiling something like
+        // let a = new N.T()
+        // Let's just stay away from generics...
+        public override bool ContainsGenericParameters
+        {
+            get
+            {
+                
+                return _IsGenericType;
+            }
+        }
+
+        // This one seems to be checked when in IDE.
+        // let b = N.T(
+        protected override bool IsValueTypeImpl()
+        {
+            
+            return _IsValueType;
+        }
+
+        // This one seems to be checked when in IDE.
+        // let b = N.T(
+        protected override bool IsByRefImpl()
+        {
+            
+            return _IsByRef;
+        }
+
+        // This one seems to be checked when in IDE.
+        // let b = N.T(
+        public override bool IsEnum
+        {
+            get
+            {
+                
+                return _IsEnum;
+            }
+        }
+
+        // This one seems to be checked when in IDE.
+        // let b = N.T(
+        protected override bool IsPointerImpl()
+        {
+            
+            return _IsPointer;
+        }
+
+        public override string AssemblyQualifiedName
+        {
+            get 
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override Guid GUID
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        protected override System.Reflection.ConstructorInfo GetConstructorImpl(System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder binder, System.Reflection.CallingConventions callConvention, Type[] types, System.Reflection.ParameterModifier[] modifiers)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override Type GetElementType()
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override Type GetInterface(string name, bool ignoreCase)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override System.Reflection.MemberInfo[] GetMembers(System.Reflection.BindingFlags bindingAttr)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        protected override System.Reflection.MethodInfo GetMethodImpl(string name, System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder binder, System.Reflection.CallingConventions callConvention, Type[] types, System.Reflection.ParameterModifier[] modifiers)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        protected override bool HasElementTypeImpl()
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override object InvokeMember(string name, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, object target, object[] args, System.Reflection.ParameterModifier[] modifiers, System.Globalization.CultureInfo culture, string[] namedParameters)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        protected override bool IsCOMObjectImpl()
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        protected override bool IsPrimitiveImpl()
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override System.Reflection.Module Module
+        {
+            get {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override bool IsDefined(Type attributeType, bool inherit)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override MethodBase DeclaringMethod
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.DeclaringMethod;
+            }
+        }
+
+        // This one is invoked by the F# compiler!
+        public override Type DeclaringType
+        {
+            get
+            {
+                
+                return null; // base.DeclaringType;
+            }
+        }
+
+        public override Type[] FindInterfaces(TypeFilter filter, object filterCriteria)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.FindInterfaces(filter, filterCriteria);
+        }
+
+        public override MemberInfo[] FindMembers(MemberTypes memberType, BindingFlags bindingAttr, MemberFilter filter, object filterCriteria)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.FindMembers(memberType, bindingAttr, filter, filterCriteria);
+        }
+
+        public override GenericParameterAttributes GenericParameterAttributes
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.GenericParameterAttributes;
+            }
+        }
+
+        public override int GenericParameterPosition
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.GenericParameterPosition;
+            }
+        }
+
+        public override int GetArrayRank()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetArrayRank();
+        }
+
+        public override MemberInfo[] GetDefaultMembers()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetDefaultMembers();
+        }
+
+        public override string GetEnumName(object value)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetEnumName(value);
+        }
+
+        public override string[] GetEnumNames()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetEnumNames();
+        }
+
+        public override Type GetEnumUnderlyingType()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetEnumUnderlyingType();
+        }
+
+        public override Array GetEnumValues()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetEnumValues();
+        }
+
+        public override EventInfo[] GetEvents()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetEvents();
+        }
+
+        public override Type[] GetGenericParameterConstraints()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetGenericParameterConstraints();
+        }
+
+        public override Type GetGenericTypeDefinition()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetGenericTypeDefinition();
+        }
+
+        public override InterfaceMapping GetInterfaceMap(Type interfaceType)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetInterfaceMap(interfaceType);
+        }
+
+        public override MemberInfo[] GetMember(string name, BindingFlags bindingAttr)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetMember(name, bindingAttr);
+        }
+
+        public override MemberInfo[] GetMember(string name, MemberTypes type, BindingFlags bindingAttr)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetMember(name, type, bindingAttr);
+        }
+
+        protected override TypeCode GetTypeCodeImpl()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetTypeCodeImpl();
+        }
+
+        public override bool IsAssignableFrom(Type c)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.IsAssignableFrom(c);
+        }
+
+        protected override bool IsContextfulImpl()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.IsContextfulImpl();
+        }
+
+        public override bool IsEnumDefined(object value)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.IsEnumDefined(value);
+        }
+
+        public override bool IsEquivalentTo(Type other)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.IsEquivalentTo(other);
+        }
+
+        public override bool IsGenericParameter
+        {
+            get
+            {
+                return _IsGenericType;    
+            }
+        }
+
+        public override bool IsInstanceOfType(object o)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.IsInstanceOfType(o);
+        }
+
+        protected override bool IsMarshalByRefImpl()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.IsMarshalByRefImpl();
+        }
+
+        public override bool IsSecurityCritical
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.IsSecurityCritical;
+            }
+        }
+
+        public override bool IsSecuritySafeCritical
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.IsSecuritySafeCritical;
+            }
+        }
+
+        public override bool IsSecurityTransparent
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.IsSecurityTransparent;
+            }
+        }
+
+        public override bool IsSerializable
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.IsSerializable;
+            }
+        }
+
+        public override bool IsSubclassOf(Type c)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.IsSubclassOf(c);
+        }
+
+        public override Type MakeArrayType()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.MakeArrayType();
+        }
+
+        public override Type MakeArrayType(int rank)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.MakeArrayType(rank);
+        }
+
+        public override Type MakeByRefType()
+        {
+            return base.MakeByRefType();
+        }
+
+        public override Type MakeGenericType(params Type[] typeArguments)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.MakeGenericType(typeArguments);
+        }
+
+        public override Type MakePointerType()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.MakePointerType();
+        }
+
+        public override MemberTypes MemberType
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.MemberType;
+            }
+        }
+
+        public override int MetadataToken
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.MetadataToken;
+            }
+        }
+
+        public override Type ReflectedType
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.ReflectedType;
+            }
+        }
+
+        public override System.Runtime.InteropServices.StructLayoutAttribute StructLayoutAttribute
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.StructLayoutAttribute;
+            }
+        }
+
+        public override RuntimeTypeHandle TypeHandle
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.TypeHandle;
+            }
+        }
+
+        public override string ToString()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.ToString();
+        }
+
+        public override IList<CustomAttributeData> GetCustomAttributesData()
+        {
+            var attrs = new List<CustomAttributeData>();
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderXmlDocAttribute("This is a synthetic type created by me!")));
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderDefinitionLocationAttribute() { Column = 5, FilePath = "File.fs", Line = 3 }));
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderEditorHideMethodsAttribute()));
+            return attrs;
+        }
+    }
+
+}
diff --git a/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithAdequateComment/TypeProviderInCSharp.cs b/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithAdequateComment/TypeProviderInCSharp.cs
new file mode 100644
index 0000000..e4c569b
--- /dev/null
+++ b/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithAdequateComment/TypeProviderInCSharp.cs
@@ -0,0 +1,150 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Microsoft.FSharp.Core.CompilerServices;
+using Microsoft.FSharp.Quotations;
+using System.Reflection;
+using System.Diagnostics;
+
+[assembly: TypeProviderAssembly()]
+
+namespace TypeProviderInCSharp
+{
+    //namespace N
+    //{
+    //    class S
+    //    {
+    //        public int instanceField;
+    //        public S(int x)
+    //        {
+    //            instanceField = x;
+    //        }
+    //    }
+    //}
+
+    class Namespace1 : IProvidedNamespace
+    {
+        const string _Namespace = "N";
+        const string _Name = "T";
+
+        // Type myType = new myType(typeof(N.S), "Bad.Name", typeof(Action), true);
+        Type myType = new ArtificialType(_Namespace, _Name, false, basetype: typeof(object), isValueType: false, isByRef: false, isEnum: false, IsPointer: false);
+
+        public IProvidedNamespace[] GetNestedNamespaces()
+        {
+
+            return new IProvidedNamespace[] { };
+        }
+
+        public Type[] GetTypes()
+        {
+
+            return new Type[] { myType };
+        }
+
+        public string NamespaceName
+        {
+            get { return _Namespace; }
+        }
+
+        public Type ResolveTypeName(string typeName)
+        {
+
+            if (typeName == _Name)
+            {
+                return myType;
+            }
+            return null;
+        }
+    }
+
+    [TypeProvider()]
+    public class TypeProvider : ITypeProvider
+    {
+        void IDisposable.Dispose()
+        {
+        }
+        private void Param(int staticParam)
+        {
+        }
+
+        public Type ApplyStaticArguments(Type typeWithoutArguments, string[] typeNameWithArguments, object[] staticArguments)
+        {
+            //Console.WriteLine("Hello from ApplyStaticArguments");
+            //var n = new myType(typeof(N.S), "S,\"1\"", typeof(object), false);
+            //return n;
+
+            return null;
+        }
+
+        public FSharpExpr GetInvokerExpression(System.Reflection.MethodBase syntheticMethodBase, FSharpExpr[] parameters)
+        {
+
+            if (syntheticMethodBase is System.Reflection.ConstructorInfo)
+            {
+                var ac = syntheticMethodBase as ArtificialConstructorInfo;
+                if (ac.DeclaringType.FullName == "N.T")
+                {
+                    return FSharpExpr.DefaultValue(ac.DeclaringType.BaseType);
+                }
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+            else if (syntheticMethodBase is System.Reflection.MethodInfo)
+            {
+                var am = syntheticMethodBase as ArtificialMethodInfo;
+                if (am.DeclaringType.FullName == "N.T" && am.Name == "M")
+                {
+                    return FSharpExpr.Lambda(FSharpVar.Global("", typeof(int[])), FSharpExpr.Value<int[]>(new[] { 1, 2, 3 }));
+                }
+                else if (am.DeclaringType.FullName == "N.T" && am.Name == "get_StaticProp")
+                {
+                    return FSharpExpr.Lambda(FSharpVar.Global("", typeof(decimal)), FSharpExpr.Value<decimal>(4.2M));
+                }
+                else if (am.DeclaringType.FullName == "N.T" && am.Name == "add_Event1")
+                {
+                    // Dummy expr... since we do not care about what it really does...
+                    return FSharpExpr.Lambda(FSharpVar.Global("", typeof(int)), FSharpExpr.Value<int>(1));
+                }
+                else if (am.DeclaringType.FullName == "N.T" && am.Name == "remove_Event1")
+                {
+                    // Dummy expr... since we do not care about what it really does...
+                    return FSharpExpr.Lambda(FSharpVar.Global("", typeof(int)), FSharpExpr.Value<int>(1));
+                }
+                else
+                {
+                    Debug.Assert(false, "NYI");
+                    throw new NotImplementedException();
+                }
+            }
+            else
+            {
+                Debug.Assert(false, "GetInvokerExpression() invoked with neither ConstructorInfo nor MethodInfo!");
+                return null;
+            }
+            //Expression<Func<S>> e = () => new S(9);
+            //return e.Body;
+
+            //throw new NotImplementedException();
+        }
+
+        public IProvidedNamespace[] GetNamespaces()
+        {
+
+            return new IProvidedNamespace[] { new Namespace1() };
+        }
+
+        public System.Reflection.ParameterInfo[] GetStaticParameters(Type typeWithoutArguments)
+        {
+
+            // No StaticParams
+            return new ParameterInfo[] { /* new myParameterInfo() */ };
+        }
+
+        public event EventHandler Invalidate;
+        public byte[] GetGeneratedAssemblyContents(Assembly assembly) { throw (new Exception("GetGeneratedAssemblyContents - only erased types were provided!!")); }
+    }
+}
diff --git a/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithAdequateComment/XmlDocAttributeWithAdequateComment.csproj b/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithAdequateComment/XmlDocAttributeWithAdequateComment.csproj
new file mode 100644
index 0000000..0d2aa6f
--- /dev/null
+++ b/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithAdequateComment/XmlDocAttributeWithAdequateComment.csproj
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information. -->
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <FSharpSourcesRoot>..\..\..\..\..\src</FSharpSourcesRoot>
+    <ProjectLanguage>CSharp</ProjectLanguage>
+  </PropertyGroup>
+  <Import Project="$(FSharpSourcesRoot)\FSharpSource.settings.targets" />
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{243A81AC-A954-4601-833A-60EEEFB00FCD}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AssemblyName>XmlDocAttributeWithAdequateComment</AssemblyName>
+    <WarningLevel>4</WarningLevel>
+    <NoWarn>0169;0067</NoWarn>
+    <DefineConstants>DEBUG;TRACE;$(DefineConstants)</DefineConstants>
+    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+    <OutputPath>$(FSharpSourcesRoot)\..\$(Configuration)\$(TargetFramework)\bin\UnitTestsResources\MockTypeProviders</OutputPath>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+    <ProjectReference Include="$(FSharpSourcesRoot)\fsharp\FSharp.Core\FSharp.Core.fsproj">
+      <Project>{DED3BBD7-53F4-428A-8C9F-27968E768605}</Project>
+      <Name>FSharp.Core</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="ArtificalEventInfo.cs" />
+    <Compile Include="ArtificialConstructorInfo.cs" />
+    <Compile Include="ArtificialMethodInfo.cs" />
+    <Compile Include="ArtificialParamInfo.cs" />
+    <Compile Include="ArtificialType.cs" />
+    <Compile Include="ArtificialPropertyInfo.cs" />
+    <Compile Include="TypeProviderInCSharp.cs" />
+    <Compile Include="..\Helpers.cs" />
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+</Project>
diff --git a/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithEmptyComment/ArtificalEventInfo.cs b/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithEmptyComment/ArtificalEventInfo.cs
new file mode 100644
index 0000000..2a43594
--- /dev/null
+++ b/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithEmptyComment/ArtificalEventInfo.cs
@@ -0,0 +1,130 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Reflection;
+using Microsoft.FSharp.Core.CompilerServices;
+
+namespace TypeProviderInCSharp
+{
+    class ArtificalEventInfo : EventInfo
+    {
+        string _Name;
+        Type _DeclaringType;
+        Type _EventHandleType;
+        MethodInfo _AddMethod;
+        MethodInfo _RemoveMethod;
+
+        public ArtificalEventInfo(string Name, Type DeclaringType, Type EventHandleType)
+        {
+            _Name = Name;
+            _DeclaringType = DeclaringType;
+            _EventHandleType = EventHandleType;
+
+            _AddMethod = new ArtificialMethodInfo("add_" + _Name, _DeclaringType, typeof(void), MethodAttributes.FamANDAssem | MethodAttributes.Family | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.Public);
+            _RemoveMethod = new ArtificialMethodInfo("remove_" + _Name, _DeclaringType, typeof(void), MethodAttributes.FamANDAssem | MethodAttributes.Family | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.Public);
+        }
+
+        // This one is invoked
+        public override Type EventHandlerType
+        {
+            get
+            {
+                
+                return _EventHandleType;
+            }
+        }
+
+        public override string Name
+        {
+            get 
+            { 
+                
+                return _Name;
+            }
+        }
+
+        public override Type DeclaringType
+        {
+            get
+            {
+                
+                return _DeclaringType;
+            }
+        }
+
+        // This one is needed
+        public override MethodInfo GetAddMethod(bool nonPublic)
+        {
+            
+            Debug.Assert(!nonPublic, "GetAddMethod() was called with nonPublic=true");
+            return _AddMethod;
+        }
+
+        // This one is needed
+        public override MethodInfo GetRemoveMethod(bool nonPublic)
+        {
+            
+            Debug.Assert(!nonPublic, "GetRemoveMethod() was called with nonPublic=true");
+            return _RemoveMethod;
+        }
+
+        public override object[] GetCustomAttributes(Type attributeType, bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        public override EventAttributes Attributes
+        {
+            get
+            {
+                
+                return EventAttributes.None;
+            }
+        }
+
+        public override MethodInfo GetRaiseMethod(bool nonPublic)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        public override object[] GetCustomAttributes(bool inherit)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override bool IsDefined(Type attributeType, bool inherit)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override Type ReflectedType
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override IList<CustomAttributeData> GetCustomAttributesData()
+        {
+            var attrs = new List<CustomAttributeData>();
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderXmlDocAttribute(string.Format(""))));
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderDefinitionLocationAttribute() { Column = 5 + this._DeclaringType.Name.Length, FilePath = "", Line = 3 }));
+            // attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderEditorHideMethodsAttribute()));
+            return attrs;
+        }
+
+    }
+}
diff --git a/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithEmptyComment/ArtificialConstructorInfo.cs b/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithEmptyComment/ArtificialConstructorInfo.cs
new file mode 100644
index 0000000..8910578
--- /dev/null
+++ b/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithEmptyComment/ArtificialConstructorInfo.cs
@@ -0,0 +1,135 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Reflection;
+using Microsoft.FSharp.Core.CompilerServices;
+
+namespace TypeProviderInCSharp
+{
+    class ArtificialConstructorInfo : ConstructorInfo
+    {
+        Type _DeclaringType;
+        ParameterInfo[] _ParameterInfo;
+
+        public ArtificialConstructorInfo(Type DeclaringType, ParameterInfo[] ParamInfo)
+        {
+            _DeclaringType = DeclaringType;
+            _ParameterInfo = ParamInfo;
+        }
+
+        public override Type DeclaringType
+        {
+            get
+            {
+                
+                return _DeclaringType;
+            }
+        }
+
+        // This one is invoked
+        public override ParameterInfo[] GetParameters()
+        {
+            
+            return _ParameterInfo;
+        }
+
+        // This one is indeed invoked
+        // I believe we should always return ".ctor"
+        public override string Name
+        {
+            get
+            {
+                
+                return ".ctor";
+            }
+        }
+
+        // Does it matter what we return here?
+        // This property is definitely checked by the compiler in code like this:
+        // let _ = new N.T()
+        // I copied the attribute set from the .ctor of System.DateTime - the documentation on MSDN assumes that one is already familiar with
+        // what they mean (=totally useless, as often happens)
+        public override MethodAttributes Attributes
+        {
+            get
+            {
+                
+                return MethodAttributes.FamANDAssem | MethodAttributes.Family | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName;
+            }
+        }
+
+        public override object[] GetCustomAttributes(Type attributeType, bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        public override object Invoke(BindingFlags invokeAttr, Binder binder, object[] parameters, System.Globalization.CultureInfo culture)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override MethodImplAttributes GetMethodImplementationFlags()
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override object Invoke(object obj, BindingFlags invokeAttr, Binder binder, object[] parameters, System.Globalization.CultureInfo culture)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override RuntimeMethodHandle MethodHandle
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override object[] GetCustomAttributes(bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        public override bool IsDefined(Type attributeType, bool inherit)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override Type ReflectedType
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override IList<CustomAttributeData> GetCustomAttributesData()
+        {
+            var attrs = new List<CustomAttributeData>();
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderXmlDocAttribute(string.Format(""))));
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderDefinitionLocationAttribute() { Column = 5 + this._DeclaringType.Name.Length, FilePath = "", Line = 3 }));
+            // attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderEditorHideMethodsAttribute()));
+            return attrs;
+        }
+
+    }
+}
diff --git a/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithEmptyComment/ArtificialMethodInfo.cs b/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithEmptyComment/ArtificialMethodInfo.cs
new file mode 100644
index 0000000..189295b
--- /dev/null
+++ b/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithEmptyComment/ArtificialMethodInfo.cs
@@ -0,0 +1,168 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Reflection;
+using Microsoft.FSharp.Core.CompilerServices;
+
+namespace TypeProviderInCSharp
+{
+    class ArtificialMethodInfo : MethodInfo
+    {
+        string _Name;
+        Type _DeclaringType;
+        Type _ReturnType;
+        MethodAttributes _MethodAttributes;
+
+        public ArtificialMethodInfo(string Name, Type DeclaringType, Type ReturnType, MethodAttributes MethodAttributes)
+        {
+            _Name = Name;
+            _DeclaringType = DeclaringType;
+            _ReturnType = ReturnType;
+            _MethodAttributes = MethodAttributes;
+        }
+
+        public override string Name
+        {
+            get 
+            { 
+                
+                return _Name;
+            }
+        }
+
+        public override Type DeclaringType
+        {
+            get
+            {
+                
+                return _DeclaringType;
+            }
+        }
+
+        // Make the method Public and Static - 
+        // TODO: should be configurable in the ctor...
+        public override MethodAttributes Attributes
+        {
+            get
+            {
+                
+                return _MethodAttributes;
+            }
+        }
+
+        // No params
+        // TODO: should be configurable in the ctor...
+        public override ParameterInfo[] GetParameters()
+        {
+            
+            return new ParameterInfo[] {  };
+        }
+
+        public override ParameterInfo ReturnParameter
+        {
+            get
+            {
+                //
+                //var retvalpi = new ArtificialParamInfo(typeof(List<>), true);
+                //return retvalpi;
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+
+            }
+        }
+
+        public override Type ReturnType
+        {
+            get
+            {
+                
+                return _ReturnType;
+            }
+        }
+
+        public override MethodInfo GetBaseDefinition()
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override ICustomAttributeProvider ReturnTypeCustomAttributes
+        {
+            get 
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override MethodImplAttributes GetMethodImplementationFlags()
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override object Invoke(object obj, BindingFlags invokeAttr, Binder binder, object[] parameters, System.Globalization.CultureInfo culture)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override RuntimeMethodHandle MethodHandle
+        {
+            get 
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override object[] GetCustomAttributes(Type attributeType, bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        public override object[] GetCustomAttributes(bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        public override bool IsDefined(Type attributeType, bool inherit)
+        {
+            
+            Debug.Assert(false, "NYI"); 
+            throw new NotImplementedException();
+        }
+
+        public override Type ReflectedType
+        {
+            get 
+            { 
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override IList<CustomAttributeData> GetCustomAttributesData()
+        {
+            var attrs = new List<CustomAttributeData>();
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderXmlDocAttribute(string.Format(""))));
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderDefinitionLocationAttribute() { Column = 22 + this._DeclaringType.Name.Length, FilePath = "", Line = 3 }));
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderEditorHideMethodsAttribute()));
+            return attrs;
+        }
+
+    }
+}
diff --git a/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithEmptyComment/ArtificialParamInfo.cs b/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithEmptyComment/ArtificialParamInfo.cs
new file mode 100644
index 0000000..6624f2d
--- /dev/null
+++ b/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithEmptyComment/ArtificialParamInfo.cs
@@ -0,0 +1,156 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Reflection;
+using Microsoft.FSharp.Core.CompilerServices;
+
+namespace TypeProviderInCSharp
+{
+    public class ArtificialParamInfo : ParameterInfo
+    {
+        Type _type;
+        bool _isRetVal;
+
+        public ArtificialParamInfo(Type type, bool isRetVal)
+        {
+            _type = type;
+            _isRetVal = IsRetval;
+        }
+
+        // TODO: allow more customizations...
+        public override ParameterAttributes Attributes
+        {
+            get
+            {
+                return _isRetVal ? ParameterAttributes.Retval : ParameterAttributes.None;
+            }
+        }
+
+        public override Type ParameterType
+        {
+            get
+            {
+                return _type;
+            }
+        }
+
+        public override object DefaultValue
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override bool Equals(object obj)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override object[] GetCustomAttributes(bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        public override object[] GetCustomAttributes(Type attributeType, bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        public override int GetHashCode()
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override Type[] GetOptionalCustomModifiers()
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override Type[] GetRequiredCustomModifiers()
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override bool IsDefined(Type attributeType, bool inherit)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override MemberInfo Member
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override int MetadataToken
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override string Name
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override int Position
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override object RawDefaultValue
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override string ToString()
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+    }
+
+}
diff --git a/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithEmptyComment/ArtificialPropertyInfo.cs b/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithEmptyComment/ArtificialPropertyInfo.cs
new file mode 100644
index 0000000..1f47321
--- /dev/null
+++ b/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithEmptyComment/ArtificialPropertyInfo.cs
@@ -0,0 +1,181 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Reflection;
+using Microsoft.FSharp.Core.CompilerServices;
+
+namespace TypeProviderInCSharp
+{
+    class ArtificialPropertyInfo : PropertyInfo
+    {
+        string _Name;
+        bool _CanRead;
+        bool _CanWrite;
+        Type _DeclaringType;
+        Type _PropertyType;
+
+        MethodInfo _GetMethod;
+        MethodInfo _SetMethod;
+
+        public ArtificialPropertyInfo(string Name, Type DeclaringType, Type PropertyType, bool CanRead, bool CanWrite)
+        {
+            _Name = Name;
+            _DeclaringType = DeclaringType;
+            _PropertyType = PropertyType;
+            _CanRead = CanRead;
+            _CanWrite = CanWrite;
+
+            if(CanRead)
+                _GetMethod = new ArtificialMethodInfo("get_" + _Name, _DeclaringType, _PropertyType, MethodAttributes.Public | MethodAttributes.Static);
+            if (CanWrite)
+                _SetMethod = new ArtificialMethodInfo("set_" + _Name, _DeclaringType, null /* ?? */, MethodAttributes.Public | MethodAttributes.Static);
+
+        }
+
+        // The name of this property...
+        public override string Name
+        {
+            get
+            {
+                
+                return _Name;
+            }
+        }
+
+        // Needed
+        public override bool CanRead
+        {
+            get
+            {
+                
+                return _CanRead;
+            }
+        }
+
+        // If CanRead is true, this one gets invoked.
+        public override MethodInfo GetGetMethod(bool nonPublic)
+        {
+            
+            Debug.Assert(!nonPublic, "GetGetMethod was invoked with nonPublic=true");
+            return _GetMethod;
+        }
+
+        // Why is this invoked?
+        public override ParameterInfo[] GetIndexParameters()
+        {
+            
+            return new ParameterInfo[] { /* new ArtificialParamInfo(typeof(int), isRetVal: false), new ArtificialParamInfo(typeof(decimal), isRetVal: false) */};
+        }
+
+        // If CanRead is false, this one gets invoked... without checking 'CanWrite' (?)
+        public override MethodInfo GetSetMethod(bool nonPublic)
+        {
+            
+            return _SetMethod;
+        }
+
+        public override bool CanWrite
+        {
+            get
+            {
+                
+                return _CanWrite;
+            }
+        }
+
+        // Interestingly enough, this one seems to be invoked only when I hover over the property in the IDE...
+        public override Type PropertyType
+        {
+            get
+            {
+                
+                return _PropertyType;
+            }
+        }
+
+        // Interestingly enough, this one seems to be invoked only when I hover over the property in the IDE...
+        public override Type DeclaringType
+        {
+            get
+            {
+                
+                return _DeclaringType;
+            }
+        }
+
+        public override object[] GetCustomAttributes(Type attributeType, bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+
+        public override PropertyAttributes Attributes
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override MethodInfo[] GetAccessors(bool nonPublic)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override object GetValue(object obj, BindingFlags invokeAttr, Binder binder, object[] index, System.Globalization.CultureInfo culture)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override void SetValue(object obj, object value, BindingFlags invokeAttr, Binder binder, object[] index, System.Globalization.CultureInfo culture)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override object[] GetCustomAttributes(bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        public override bool IsDefined(Type attributeType, bool inherit)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override Type ReflectedType
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override IList<CustomAttributeData> GetCustomAttributesData()
+        {
+            var attrs = new List<CustomAttributeData>();
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderXmlDocAttribute("")));
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderDefinitionLocationAttribute() { Column = 21, FilePath = "File.fs", Line = 3 }));
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderEditorHideMethodsAttribute()));
+            return attrs;
+        }
+
+    }
+}
diff --git a/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithEmptyComment/ArtificialType.cs b/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithEmptyComment/ArtificialType.cs
new file mode 100644
index 0000000..2af6345
--- /dev/null
+++ b/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithEmptyComment/ArtificialType.cs
@@ -0,0 +1,768 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Reflection;
+using Microsoft.FSharp.Core.CompilerServices;
+
+namespace TypeProviderInCSharp
+{
+    public class ArtificialType : Type
+    {
+        string _Namespace;
+        string _Name;
+        bool _IsGenericType;
+        bool _IsValueType;  // value type = not class / not interface
+        bool _IsByRef;      // is the value passed by reference?
+        bool _IsEnum;
+        bool _IsPointer;
+
+        Type _BaseType;
+        MethodInfo _Method1;
+        PropertyInfo _Property1;
+        EventInfo _Event1;
+        FieldInfo _Field1;
+        ConstructorInfo _Ctor1;
+
+        public ArtificialType(string @namespace, string name, bool isGenericType, Type basetype, bool isValueType, bool isByRef, bool isEnum, bool IsPointer)
+        {
+            _Name = name;
+            _Namespace = @namespace;
+            _IsGenericType = isGenericType;
+            _BaseType = basetype;
+            _IsValueType = isValueType;
+            _IsByRef = isByRef;
+            _IsEnum = isEnum;
+            _IsPointer = IsPointer;
+            _Method1 = new ArtificialMethodInfo("M", this, typeof(int[]), MethodAttributes.Public | MethodAttributes.Static);
+            _Property1 = new ArtificialPropertyInfo("StaticProp", this, typeof(decimal), true, false);
+            _Event1 = new ArtificalEventInfo("Event1", this, typeof(EventHandler));
+            _Ctor1 = new ArtificialConstructorInfo(this, new ParameterInfo[] {} );  // parameter-less ctor
+        }
+
+        public override System.Reflection.Assembly Assembly
+        {
+            get 
+            { 
+                
+                return Assembly.GetExecutingAssembly();
+            }
+        }
+
+        public override string Name
+        {
+            get 
+            { 
+                
+                return _Name;
+            }
+        }
+
+        public override Type BaseType
+        {
+            get
+            {
+                
+                return _BaseType;
+            }
+        }
+
+        public override string Namespace
+        {
+            get
+            {
+                
+                return _Namespace;
+            }
+        }
+
+        public override string FullName
+        {
+            get
+            { 
+                
+                return string.Format("{0}.{1}", _Namespace, _Name);
+            }
+        }
+
+        public override object[] GetCustomAttributes(Type attributeType, bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        public override object[] GetCustomAttributes(bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        // TODO: what is this?
+        protected override System.Reflection.TypeAttributes GetAttributeFlagsImpl()
+        {
+
+            return TypeAttributes.Class | TypeAttributes.Public | (TypeAttributes)0x40000000; // add the special flag to indicate an erased type, see TypeProviderTypeAttributes
+        }
+
+        // This one seems to be invoked when in IDE, I type something like:
+        // let _ = typeof<N.
+        // In this case => no constructors
+        public override System.Reflection.ConstructorInfo[] GetConstructors(System.Reflection.BindingFlags bindingAttr)
+        {
+            
+            // According to the spec, we should only expect these 4, so we guard against that here!
+            Debug.Assert(bindingAttr == (BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly), "bindingAttr has value not according to the spec!");
+            if (_Ctor1!=null) 
+                return new System.Reflection.ConstructorInfo[] { _Ctor1 };
+            else
+                return new System.Reflection.ConstructorInfo[] { };
+        }
+
+        // When you start typing more interesting things like...
+        // let a = N.T.M()
+        // this one gets invoked...
+        public override System.Reflection.MethodInfo[] GetMethods(System.Reflection.BindingFlags bindingAttr)
+        {
+            
+            // According to the spec, we should only expect these 4, so we guard against that here!
+            Debug.Assert(bindingAttr == (BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly), "bindingAttr has value not according to the spec!");
+            return new[] { _Method1 };
+        }
+
+        // This method is called when in the source file we have something like:
+        // - N.T.StaticProp 
+        // (most likely also when we have an instance prop...)
+        // name -> "StaticProp"
+        protected override System.Reflection.PropertyInfo GetPropertyImpl(string name, System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder binder, Type returnType, Type[] types, System.Reflection.ParameterModifier[] modifiers)
+        {
+            
+            // According to the spec, we should only expect these 4, so we guard against that here!
+            Debug.Assert(bindingAttr == (BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly), "bindingAttr has value not according to the spec!");
+            Debug.Assert(binder == null && returnType == null && types == null && modifiers == null, "One of binder, returnType, types, or modifiers was not null");
+            if (name == _Property1.Name)
+                return _Property1;
+            else
+                return null;
+        }
+
+        // Advertise our property...
+        // I think that is this one returns an empty array => you don't get intellisense/autocomplete in IDE/FSI
+        public override System.Reflection.PropertyInfo[] GetProperties(System.Reflection.BindingFlags bindingAttr)
+        {
+            
+            // According to the spec, we should only expect these 4, so we guard against that here!
+            Debug.Assert(bindingAttr == (BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly), "bindingAttr has value not according to the spec!");
+            return new PropertyInfo[] { _Property1 };
+        }
+
+        // No fields...
+        public override System.Reflection.FieldInfo GetField(string name, System.Reflection.BindingFlags bindingAttr)
+        {
+            
+            // According to the spec, we should only expect these 4, so we guard against that here!
+            Debug.Assert(bindingAttr == (BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly), "bindingAttr has value not according to the spec!");
+            return null;
+        }
+
+        public override System.Reflection.FieldInfo[] GetFields(System.Reflection.BindingFlags bindingAttr)
+        {
+            
+            // According to the spec, we should only expect these 4, so we guard against that here!
+            Debug.Assert(bindingAttr == (BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly), "bindingAttr has value not according to the spec!");
+            return new System.Reflection.FieldInfo[] { };
+        }
+
+        // Events
+        public override System.Reflection.EventInfo GetEvent(string name, System.Reflection.BindingFlags bindingAttr)
+        {
+            
+            // According to the spec, we should only expect these 4, so we guard against that here!
+            Debug.Assert(bindingAttr == (BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly), "bindingAttr has value not according to the spec!");
+            if (_Event1 != null && _Event1.Name == name)
+                return _Event1;
+            else
+                return null;
+        }
+
+        // Events...
+        public override System.Reflection.EventInfo[] GetEvents(System.Reflection.BindingFlags bindingAttr)
+        {
+            
+            return _Event1 != null ? new [] { _Event1 } : new System.Reflection.EventInfo[] { };
+        }
+
+        // TODO: according to the spec, this should not be invoked... instead it seems like it may be invoked...
+        //       ?? I have no idea what this is used for... ??
+        public override Type UnderlyingSystemType
+        {
+            get
+            {
+                
+                return null;
+            }
+        }
+
+        // According to the spec, this should always be 'false'
+        protected override bool IsArrayImpl()
+        {
+            
+            return false;    
+        }
+
+        // No interfaces...
+        public override Type[] GetInterfaces()
+        {
+            
+            return new Type[] { };
+        }
+
+        // No nested type
+        // This method is invoked on the type 'T', e.g.:
+        //    let _ = N.T.M
+        // to figure out if M is a nested type.
+        public override Type GetNestedType(string name, System.Reflection.BindingFlags bindingAttr)
+        {
+            
+            return null;
+        }
+        public override Type[] GetNestedTypes(System.Reflection.BindingFlags bindingAttr)
+        {
+            
+            // According to the spec, we should only expect these 4, so we guard against that here!
+            Debug.Assert(bindingAttr == (BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly), "bindingAttr has value not according to the spec!");
+            return new Type[] { };
+        }
+
+        // This one is invoked when the type has a .ctor 
+        // and the code looks like
+        // let _ = new N.T()
+        // for example.
+        // It was observed that the
+        // TODO: cover both cases!
+        public override bool IsGenericType
+        {
+            get
+            {
+                
+                return _IsGenericType;
+            }
+        }
+
+        // This is invoked if the IsGenericType is true
+        public override Type[] GetGenericArguments()
+        {
+            
+            if (_IsGenericType)
+                return new Type[] { typeof(int), typeof(decimal), typeof(System.Guid) };        // This is currently triggering an ICE...
+            else
+            {
+                Debug.Assert(false, "Why are we here?");
+                throw new NotImplementedException();
+            }
+
+        }
+
+        // This one seems to be invoked when compiling something like
+        // let a = new N.T()
+        // Let's just stay away from generics...
+        public override bool IsGenericTypeDefinition
+        {
+            get
+            {
+                
+                return _IsGenericType;
+            }
+        }
+
+        // This one seems to be invoked when compiling something like
+        // let a = new N.T()
+        // Let's just stay away from generics...
+        public override bool ContainsGenericParameters
+        {
+            get
+            {
+                
+                return _IsGenericType;
+            }
+        }
+
+        // This one seems to be checked when in IDE.
+        // let b = N.T(
+        protected override bool IsValueTypeImpl()
+        {
+            
+            return _IsValueType;
+        }
+
+        // This one seems to be checked when in IDE.
+        // let b = N.T(
+        protected override bool IsByRefImpl()
+        {
+            
+            return _IsByRef;
+        }
+
+        // This one seems to be checked when in IDE.
+        // let b = N.T(
+        public override bool IsEnum
+        {
+            get
+            {
+                
+                return _IsEnum;
+            }
+        }
+
+        // This one seems to be checked when in IDE.
+        // let b = N.T(
+        protected override bool IsPointerImpl()
+        {
+            
+            return _IsPointer;
+        }
+
+        public override string AssemblyQualifiedName
+        {
+            get 
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override Guid GUID
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        protected override System.Reflection.ConstructorInfo GetConstructorImpl(System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder binder, System.Reflection.CallingConventions callConvention, Type[] types, System.Reflection.ParameterModifier[] modifiers)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override Type GetElementType()
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override Type GetInterface(string name, bool ignoreCase)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override System.Reflection.MemberInfo[] GetMembers(System.Reflection.BindingFlags bindingAttr)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        protected override System.Reflection.MethodInfo GetMethodImpl(string name, System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder binder, System.Reflection.CallingConventions callConvention, Type[] types, System.Reflection.ParameterModifier[] modifiers)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        protected override bool HasElementTypeImpl()
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override object InvokeMember(string name, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, object target, object[] args, System.Reflection.ParameterModifier[] modifiers, System.Globalization.CultureInfo culture, string[] namedParameters)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        protected override bool IsCOMObjectImpl()
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        protected override bool IsPrimitiveImpl()
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override System.Reflection.Module Module
+        {
+            get {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override bool IsDefined(Type attributeType, bool inherit)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override MethodBase DeclaringMethod
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.DeclaringMethod;
+            }
+        }
+
+        // This one is invoked by the F# compiler!
+        public override Type DeclaringType
+        {
+            get
+            {
+                
+                return null; // base.DeclaringType;
+            }
+        }
+
+        public override Type[] FindInterfaces(TypeFilter filter, object filterCriteria)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.FindInterfaces(filter, filterCriteria);
+        }
+
+        public override MemberInfo[] FindMembers(MemberTypes memberType, BindingFlags bindingAttr, MemberFilter filter, object filterCriteria)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.FindMembers(memberType, bindingAttr, filter, filterCriteria);
+        }
+
+        public override GenericParameterAttributes GenericParameterAttributes
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.GenericParameterAttributes;
+            }
+        }
+
+        public override int GenericParameterPosition
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.GenericParameterPosition;
+            }
+        }
+
+        public override int GetArrayRank()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetArrayRank();
+        }
+
+        public override MemberInfo[] GetDefaultMembers()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetDefaultMembers();
+        }
+
+        public override string GetEnumName(object value)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetEnumName(value);
+        }
+
+        public override string[] GetEnumNames()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetEnumNames();
+        }
+
+        public override Type GetEnumUnderlyingType()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetEnumUnderlyingType();
+        }
+
+        public override Array GetEnumValues()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetEnumValues();
+        }
+
+        public override EventInfo[] GetEvents()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetEvents();
+        }
+
+        public override Type[] GetGenericParameterConstraints()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetGenericParameterConstraints();
+        }
+
+        public override Type GetGenericTypeDefinition()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetGenericTypeDefinition();
+        }
+
+        public override InterfaceMapping GetInterfaceMap(Type interfaceType)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetInterfaceMap(interfaceType);
+        }
+
+        public override MemberInfo[] GetMember(string name, BindingFlags bindingAttr)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetMember(name, bindingAttr);
+        }
+
+        public override MemberInfo[] GetMember(string name, MemberTypes type, BindingFlags bindingAttr)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetMember(name, type, bindingAttr);
+        }
+
+        protected override TypeCode GetTypeCodeImpl()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetTypeCodeImpl();
+        }
+
+        public override bool IsAssignableFrom(Type c)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.IsAssignableFrom(c);
+        }
+
+        protected override bool IsContextfulImpl()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.IsContextfulImpl();
+        }
+
+        public override bool IsEnumDefined(object value)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.IsEnumDefined(value);
+        }
+
+        public override bool IsEquivalentTo(Type other)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.IsEquivalentTo(other);
+        }
+
+        public override bool IsGenericParameter
+        {
+            get
+            {
+                return _IsGenericType;    
+            }
+        }
+
+        public override bool IsInstanceOfType(object o)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.IsInstanceOfType(o);
+        }
+
+        protected override bool IsMarshalByRefImpl()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.IsMarshalByRefImpl();
+        }
+
+        public override bool IsSecurityCritical
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.IsSecurityCritical;
+            }
+        }
+
+        public override bool IsSecuritySafeCritical
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.IsSecuritySafeCritical;
+            }
+        }
+
+        public override bool IsSecurityTransparent
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.IsSecurityTransparent;
+            }
+        }
+
+        public override bool IsSerializable
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.IsSerializable;
+            }
+        }
+
+        public override bool IsSubclassOf(Type c)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.IsSubclassOf(c);
+        }
+
+        public override Type MakeArrayType()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.MakeArrayType();
+        }
+
+        public override Type MakeArrayType(int rank)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.MakeArrayType(rank);
+        }
+
+        public override Type MakeByRefType()
+        {
+            return base.MakeByRefType();
+        }
+
+        public override Type MakeGenericType(params Type[] typeArguments)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.MakeGenericType(typeArguments);
+        }
+
+        public override Type MakePointerType()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.MakePointerType();
+        }
+
+        public override MemberTypes MemberType
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.MemberType;
+            }
+        }
+
+        public override int MetadataToken
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.MetadataToken;
+            }
+        }
+
+        public override Type ReflectedType
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.ReflectedType;
+            }
+        }
+
+        public override System.Runtime.InteropServices.StructLayoutAttribute StructLayoutAttribute
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.StructLayoutAttribute;
+            }
+        }
+
+        public override RuntimeTypeHandle TypeHandle
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.TypeHandle;
+            }
+        }
+
+        public override string ToString()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.ToString();
+        }
+
+        public override IList<CustomAttributeData> GetCustomAttributesData()
+        {
+            var attrs = new List<CustomAttributeData>();
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderXmlDocAttribute("")));
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderDefinitionLocationAttribute() { Column = 5, FilePath = "File.fs", Line = 3 }));
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderEditorHideMethodsAttribute()));
+            return attrs;
+        }
+    }
+
+}
diff --git a/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithEmptyComment/TypeProviderInCSharp.cs b/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithEmptyComment/TypeProviderInCSharp.cs
new file mode 100644
index 0000000..e4c569b
--- /dev/null
+++ b/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithEmptyComment/TypeProviderInCSharp.cs
@@ -0,0 +1,150 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Microsoft.FSharp.Core.CompilerServices;
+using Microsoft.FSharp.Quotations;
+using System.Reflection;
+using System.Diagnostics;
+
+[assembly: TypeProviderAssembly()]
+
+namespace TypeProviderInCSharp
+{
+    //namespace N
+    //{
+    //    class S
+    //    {
+    //        public int instanceField;
+    //        public S(int x)
+    //        {
+    //            instanceField = x;
+    //        }
+    //    }
+    //}
+
+    class Namespace1 : IProvidedNamespace
+    {
+        const string _Namespace = "N";
+        const string _Name = "T";
+
+        // Type myType = new myType(typeof(N.S), "Bad.Name", typeof(Action), true);
+        Type myType = new ArtificialType(_Namespace, _Name, false, basetype: typeof(object), isValueType: false, isByRef: false, isEnum: false, IsPointer: false);
+
+        public IProvidedNamespace[] GetNestedNamespaces()
+        {
+
+            return new IProvidedNamespace[] { };
+        }
+
+        public Type[] GetTypes()
+        {
+
+            return new Type[] { myType };
+        }
+
+        public string NamespaceName
+        {
+            get { return _Namespace; }
+        }
+
+        public Type ResolveTypeName(string typeName)
+        {
+
+            if (typeName == _Name)
+            {
+                return myType;
+            }
+            return null;
+        }
+    }
+
+    [TypeProvider()]
+    public class TypeProvider : ITypeProvider
+    {
+        void IDisposable.Dispose()
+        {
+        }
+        private void Param(int staticParam)
+        {
+        }
+
+        public Type ApplyStaticArguments(Type typeWithoutArguments, string[] typeNameWithArguments, object[] staticArguments)
+        {
+            //Console.WriteLine("Hello from ApplyStaticArguments");
+            //var n = new myType(typeof(N.S), "S,\"1\"", typeof(object), false);
+            //return n;
+
+            return null;
+        }
+
+        public FSharpExpr GetInvokerExpression(System.Reflection.MethodBase syntheticMethodBase, FSharpExpr[] parameters)
+        {
+
+            if (syntheticMethodBase is System.Reflection.ConstructorInfo)
+            {
+                var ac = syntheticMethodBase as ArtificialConstructorInfo;
+                if (ac.DeclaringType.FullName == "N.T")
+                {
+                    return FSharpExpr.DefaultValue(ac.DeclaringType.BaseType);
+                }
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+            else if (syntheticMethodBase is System.Reflection.MethodInfo)
+            {
+                var am = syntheticMethodBase as ArtificialMethodInfo;
+                if (am.DeclaringType.FullName == "N.T" && am.Name == "M")
+                {
+                    return FSharpExpr.Lambda(FSharpVar.Global("", typeof(int[])), FSharpExpr.Value<int[]>(new[] { 1, 2, 3 }));
+                }
+                else if (am.DeclaringType.FullName == "N.T" && am.Name == "get_StaticProp")
+                {
+                    return FSharpExpr.Lambda(FSharpVar.Global("", typeof(decimal)), FSharpExpr.Value<decimal>(4.2M));
+                }
+                else if (am.DeclaringType.FullName == "N.T" && am.Name == "add_Event1")
+                {
+                    // Dummy expr... since we do not care about what it really does...
+                    return FSharpExpr.Lambda(FSharpVar.Global("", typeof(int)), FSharpExpr.Value<int>(1));
+                }
+                else if (am.DeclaringType.FullName == "N.T" && am.Name == "remove_Event1")
+                {
+                    // Dummy expr... since we do not care about what it really does...
+                    return FSharpExpr.Lambda(FSharpVar.Global("", typeof(int)), FSharpExpr.Value<int>(1));
+                }
+                else
+                {
+                    Debug.Assert(false, "NYI");
+                    throw new NotImplementedException();
+                }
+            }
+            else
+            {
+                Debug.Assert(false, "GetInvokerExpression() invoked with neither ConstructorInfo nor MethodInfo!");
+                return null;
+            }
+            //Expression<Func<S>> e = () => new S(9);
+            //return e.Body;
+
+            //throw new NotImplementedException();
+        }
+
+        public IProvidedNamespace[] GetNamespaces()
+        {
+
+            return new IProvidedNamespace[] { new Namespace1() };
+        }
+
+        public System.Reflection.ParameterInfo[] GetStaticParameters(Type typeWithoutArguments)
+        {
+
+            // No StaticParams
+            return new ParameterInfo[] { /* new myParameterInfo() */ };
+        }
+
+        public event EventHandler Invalidate;
+        public byte[] GetGeneratedAssemblyContents(Assembly assembly) { throw (new Exception("GetGeneratedAssemblyContents - only erased types were provided!!")); }
+    }
+}
diff --git a/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithEmptyComment/XmlDocAttributeWithEmptyComment.csproj b/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithEmptyComment/XmlDocAttributeWithEmptyComment.csproj
new file mode 100644
index 0000000..5143f13
--- /dev/null
+++ b/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithEmptyComment/XmlDocAttributeWithEmptyComment.csproj
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information. -->
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <FSharpSourcesRoot>..\..\..\..\..\src</FSharpSourcesRoot>
+    <ProjectLanguage>CSharp</ProjectLanguage>
+  </PropertyGroup>
+  <Import Project="$(FSharpSourcesRoot)\FSharpSource.settings.targets" />
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{B4595EB6-053A-400E-AA1B-7727F1BC900F}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AssemblyName>XmlDocAttributeWithEmptyComment</AssemblyName>
+    <WarningLevel>4</WarningLevel>
+    <NoWarn>0169;0067</NoWarn>
+    <DefineConstants>DEBUG;TRACE;$(DefineConstants)</DefineConstants>
+    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+    <OutputPath>$(FSharpSourcesRoot)\..\$(Configuration)\$(TargetFramework)\bin\UnitTestsResources\MockTypeProviders</OutputPath>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+    <ProjectReference Include="$(FSharpSourcesRoot)\fsharp\FSharp.Core\FSharp.Core.fsproj">
+      <Project>{DED3BBD7-53F4-428A-8C9F-27968E768605}</Project>
+      <Name>FSharp.Core</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="ArtificalEventInfo.cs" />
+    <Compile Include="ArtificialConstructorInfo.cs" />
+    <Compile Include="ArtificialMethodInfo.cs" />
+    <Compile Include="ArtificialParamInfo.cs" />
+    <Compile Include="ArtificialType.cs" />
+    <Compile Include="ArtificialPropertyInfo.cs" />
+    <Compile Include="TypeProviderInCSharp.cs" />
+    <Compile Include="..\Helpers.cs" />
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+</Project>
diff --git a/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithLocalizedComment/ArtificalEventInfo.cs b/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithLocalizedComment/ArtificalEventInfo.cs
new file mode 100644
index 0000000..89e2021
--- /dev/null
+++ b/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithLocalizedComment/ArtificalEventInfo.cs
@@ -0,0 +1,129 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Reflection;
+using Microsoft.FSharp.Core.CompilerServices;
+
+namespace TypeProviderInCSharp
+{
+    class ArtificalEventInfo : EventInfo
+    {
+        string _Name;
+        Type _DeclaringType;
+        Type _EventHandleType;
+        MethodInfo _AddMethod;
+        MethodInfo _RemoveMethod;
+
+        public ArtificalEventInfo(string Name, Type DeclaringType, Type EventHandleType)
+        {
+            _Name = Name;
+            _DeclaringType = DeclaringType;
+            _EventHandleType = EventHandleType;
+
+            _AddMethod = new ArtificialMethodInfo("add_" + _Name, _DeclaringType, typeof(void), MethodAttributes.FamANDAssem | MethodAttributes.Family | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.Public);
+            _RemoveMethod = new ArtificialMethodInfo("remove_" + _Name, _DeclaringType, typeof(void), MethodAttributes.FamANDAssem | MethodAttributes.Family | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.Public);
+        }
+
+        // This one is invoked
+        public override Type EventHandlerType
+        {
+            get
+            {
+                
+                return _EventHandleType;
+            }
+        }
+
+        public override string Name
+        {
+            get 
+            { 
+                
+                return _Name;
+            }
+        }
+
+        public override Type DeclaringType
+        {
+            get
+            {
+                
+                return _DeclaringType;
+            }
+        }
+
+        // This one is needed
+        public override MethodInfo GetAddMethod(bool nonPublic)
+        {
+            
+            Debug.Assert(!nonPublic, "GetAddMethod() was called with nonPublic=true");
+            return _AddMethod;
+        }
+
+        // This one is needed
+        public override MethodInfo GetRemoveMethod(bool nonPublic)
+        {
+            
+            Debug.Assert(!nonPublic, "GetRemoveMethod() was called with nonPublic=true");
+            return _RemoveMethod;
+        }
+
+        public override object[] GetCustomAttributes(Type attributeType, bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        public override EventAttributes Attributes
+        {
+            get
+            {
+                
+                return EventAttributes.None;
+            }
+        }
+
+        public override MethodInfo GetRaiseMethod(bool nonPublic)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override object[] GetCustomAttributes(bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        public override bool IsDefined(Type attributeType, bool inherit)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override Type ReflectedType
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override IList<CustomAttributeData> GetCustomAttributesData()
+        {
+            var attrs = new List<CustomAttributeData>();
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderXmlDocAttribute(string.Format("This is a synthetic *event* Localized!  ኤፍ ሻርፕ for {0}.{1}", this._DeclaringType.Namespace, this._DeclaringType.Name))));
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderDefinitionLocationAttribute() { Column = 5, FilePath = "File.fs", Line = 3 }));
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderEditorHideMethodsAttribute()));
+            return attrs;
+        }
+    }
+}
diff --git a/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithLocalizedComment/ArtificialConstructorInfo.cs b/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithLocalizedComment/ArtificialConstructorInfo.cs
new file mode 100644
index 0000000..7433e72
--- /dev/null
+++ b/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithLocalizedComment/ArtificialConstructorInfo.cs
@@ -0,0 +1,134 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Reflection;
+using Microsoft.FSharp.Core.CompilerServices;
+
+namespace TypeProviderInCSharp
+{
+    class ArtificialConstructorInfo : ConstructorInfo
+    {
+        Type _DeclaringType;
+        ParameterInfo[] _ParameterInfo;
+
+        public ArtificialConstructorInfo(Type DeclaringType, ParameterInfo[] ParamInfo)
+        {
+            _DeclaringType = DeclaringType;
+            _ParameterInfo = ParamInfo;
+        }
+
+        public override Type DeclaringType
+        {
+            get
+            {
+                
+                return _DeclaringType;
+            }
+        }
+
+        // This one is invoked
+        public override ParameterInfo[] GetParameters()
+        {
+            
+            return _ParameterInfo;
+        }
+
+        // This one is indeed invoked
+        // I believe we should always return ".ctor"
+        public override string Name
+        {
+            get
+            {
+                
+                return ".ctor";
+            }
+        }
+
+        // Does it matter what we return here?
+        // This property is definitely checked by the compiler in code like this:
+        // let _ = new N.T()
+        // I copied the attribute set from the .ctor of System.DateTime - the documentation on MSDN assumes that one is already familiar with
+        // what they mean (=totally useless, as often happens)
+        public override MethodAttributes Attributes
+        {
+            get
+            {
+                
+                return MethodAttributes.FamANDAssem | MethodAttributes.Family | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName;
+            }
+        }
+
+        public override object[] GetCustomAttributes(Type attributeType, bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        public override object Invoke(BindingFlags invokeAttr, Binder binder, object[] parameters, System.Globalization.CultureInfo culture)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override MethodImplAttributes GetMethodImplementationFlags()
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override object Invoke(object obj, BindingFlags invokeAttr, Binder binder, object[] parameters, System.Globalization.CultureInfo culture)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override RuntimeMethodHandle MethodHandle
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override object[] GetCustomAttributes(bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        public override bool IsDefined(Type attributeType, bool inherit)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override Type ReflectedType
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override IList<CustomAttributeData> GetCustomAttributesData()
+        {
+            var attrs = new List<CustomAttributeData>();
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderXmlDocAttribute(string.Format("This is a synthetic .ctor Localized!  ኤፍ ሻርፕ for {0}.{1}", this._DeclaringType.Namespace, this._DeclaringType.Name))));
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderDefinitionLocationAttribute() { Column = 5, FilePath = "File.fs", Line = 3 }));
+            // attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderEditorHideMethodsAttribute()));
+            return attrs;
+        }
+    }
+}
diff --git a/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithLocalizedComment/ArtificialMethodInfo.cs b/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithLocalizedComment/ArtificialMethodInfo.cs
new file mode 100644
index 0000000..6dd48a0
--- /dev/null
+++ b/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithLocalizedComment/ArtificialMethodInfo.cs
@@ -0,0 +1,167 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Reflection;
+using Microsoft.FSharp.Core.CompilerServices;
+
+namespace TypeProviderInCSharp
+{
+    class ArtificialMethodInfo : MethodInfo
+    {
+        string _Name;
+        Type _DeclaringType;
+        Type _ReturnType;
+        MethodAttributes _MethodAttributes;
+
+        public ArtificialMethodInfo(string Name, Type DeclaringType, Type ReturnType, MethodAttributes MethodAttributes)
+        {
+            _Name = Name;
+            _DeclaringType = DeclaringType;
+            _ReturnType = ReturnType;
+            _MethodAttributes = MethodAttributes;
+        }
+
+        public override string Name
+        {
+            get 
+            { 
+                
+                return _Name;
+            }
+        }
+
+        public override Type DeclaringType
+        {
+            get
+            {
+                
+                return _DeclaringType;
+            }
+        }
+
+        // Make the method Public and Static - 
+        // TODO: should be configurable in the ctor...
+        public override MethodAttributes Attributes
+        {
+            get
+            {
+                
+                return _MethodAttributes;
+            }
+        }
+
+        // No params
+        // TODO: should be configurable in the ctor...
+        public override ParameterInfo[] GetParameters()
+        {
+            
+            return new ParameterInfo[] {  };
+        }
+
+        public override ParameterInfo ReturnParameter
+        {
+            get
+            {
+                //
+                //var retvalpi = new ArtificialParamInfo(typeof(List<>), true);
+                //return retvalpi;
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+
+            }
+        }
+
+        public override Type ReturnType
+        {
+            get
+            {
+                
+                return _ReturnType;
+            }
+        }
+
+        public override MethodInfo GetBaseDefinition()
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override ICustomAttributeProvider ReturnTypeCustomAttributes
+        {
+            get 
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override MethodImplAttributes GetMethodImplementationFlags()
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override object Invoke(object obj, BindingFlags invokeAttr, Binder binder, object[] parameters, System.Globalization.CultureInfo culture)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override RuntimeMethodHandle MethodHandle
+        {
+            get 
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override object[] GetCustomAttributes(Type attributeType, bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        public override object[] GetCustomAttributes(bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        public override bool IsDefined(Type attributeType, bool inherit)
+        {
+            
+            Debug.Assert(false, "NYI"); 
+            throw new NotImplementedException();
+        }
+
+        public override Type ReflectedType
+        {
+            get 
+            { 
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override IList<CustomAttributeData> GetCustomAttributesData()
+        {
+            var attrs = new List<CustomAttributeData>();
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderXmlDocAttribute("This is a synthetic *method* Localized!  ኤፍ ሻርፕ")));
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderDefinitionLocationAttribute() { Column = 5, FilePath = "File.fs", Line = 3 }));
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderEditorHideMethodsAttribute()));
+            return attrs;
+        }
+    }
+}
diff --git a/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithLocalizedComment/ArtificialParamInfo.cs b/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithLocalizedComment/ArtificialParamInfo.cs
new file mode 100644
index 0000000..7c631b2
--- /dev/null
+++ b/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithLocalizedComment/ArtificialParamInfo.cs
@@ -0,0 +1,155 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Reflection;
+using Microsoft.FSharp.Core.CompilerServices;
+
+namespace TypeProviderInCSharp
+{
+    public class ArtificialParamInfo : ParameterInfo
+    {
+        Type _type;
+        bool _isRetVal;
+
+        public ArtificialParamInfo(Type type, bool isRetVal)
+        {
+            _type = type;
+            _isRetVal = IsRetval;
+        }
+
+        // TODO: allow more customizations...
+        public override ParameterAttributes Attributes
+        {
+            get
+            {
+                return _isRetVal ? ParameterAttributes.Retval : ParameterAttributes.None;
+            }
+        }
+
+        public override Type ParameterType
+        {
+            get
+            {
+                return _type;
+            }
+        }
+
+        public override object DefaultValue
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override bool Equals(object obj)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override object[] GetCustomAttributes(bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        public override object[] GetCustomAttributes(Type attributeType, bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        public override int GetHashCode()
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override Type[] GetOptionalCustomModifiers()
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override Type[] GetRequiredCustomModifiers()
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override bool IsDefined(Type attributeType, bool inherit)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override MemberInfo Member
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override int MetadataToken
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override string Name
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override int Position
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override object RawDefaultValue
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override string ToString()
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+    }
+}
diff --git a/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithLocalizedComment/ArtificialPropertyInfo.cs b/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithLocalizedComment/ArtificialPropertyInfo.cs
new file mode 100644
index 0000000..d02050f
--- /dev/null
+++ b/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithLocalizedComment/ArtificialPropertyInfo.cs
@@ -0,0 +1,179 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Reflection;
+using Microsoft.FSharp.Core.CompilerServices;
+
+namespace TypeProviderInCSharp
+{
+    class ArtificialPropertyInfo : PropertyInfo
+    {
+        string _Name;
+        bool _CanRead;
+        bool _CanWrite;
+        Type _DeclaringType;
+        Type _PropertyType;
+
+        MethodInfo _GetMethod;
+        MethodInfo _SetMethod;
+
+        public ArtificialPropertyInfo(string Name, Type DeclaringType, Type PropertyType, bool CanRead, bool CanWrite)
+        {
+            _Name = Name;
+            _DeclaringType = DeclaringType;
+            _PropertyType = PropertyType;
+            _CanRead = CanRead;
+            _CanWrite = CanWrite;
+
+            if(CanRead)
+                _GetMethod = new ArtificialMethodInfo("get_" + _Name, _DeclaringType, _PropertyType, MethodAttributes.Public | MethodAttributes.Static);
+            if (CanWrite)
+                _SetMethod = new ArtificialMethodInfo("set_" + _Name, _DeclaringType, null /* ?? */, MethodAttributes.Public | MethodAttributes.Static);
+
+        }
+
+        // The name of this property...
+        public override string Name
+        {
+            get
+            {
+                
+                return _Name;
+            }
+        }
+
+        // Needed
+        public override bool CanRead
+        {
+            get
+            {
+                
+                return _CanRead;
+            }
+        }
+
+        // If CanRead is true, this one gets invoked.
+        public override MethodInfo GetGetMethod(bool nonPublic)
+        {
+            
+            Debug.Assert(!nonPublic, "GetGetMethod was invoked with nonPublic=true");
+            return _GetMethod;
+        }
+
+        // Why is this invoked?
+        public override ParameterInfo[] GetIndexParameters()
+        {
+            
+            return new ParameterInfo[] { /* new ArtificialParamInfo(typeof(int), isRetVal: false), new ArtificialParamInfo(typeof(decimal), isRetVal: false) */};
+        }
+
+        // If CanRead is false, this one gets invoked... without checking 'CanWrite' (?)
+        public override MethodInfo GetSetMethod(bool nonPublic)
+        {
+            
+            return _SetMethod;
+        }
+
+        public override bool CanWrite
+        {
+            get
+            {
+                
+                return _CanWrite;
+            }
+        }
+
+        // Interestingly enough, this one seems to be invoked only when I hover over the property in the IDE...
+        public override Type PropertyType
+        {
+            get
+            {
+                
+                return _PropertyType;
+            }
+        }
+
+        // Interestingly enough, this one seems to be invoked only when I hover over the property in the IDE...
+        public override Type DeclaringType
+        {
+            get
+            {
+                
+                return _DeclaringType;
+            }
+        }
+
+        public override object[] GetCustomAttributes(Type attributeType, bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        public override PropertyAttributes Attributes
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override MethodInfo[] GetAccessors(bool nonPublic)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override object GetValue(object obj, BindingFlags invokeAttr, Binder binder, object[] index, System.Globalization.CultureInfo culture)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override void SetValue(object obj, object value, BindingFlags invokeAttr, Binder binder, object[] index, System.Globalization.CultureInfo culture)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override object[] GetCustomAttributes(bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        public override bool IsDefined(Type attributeType, bool inherit)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override Type ReflectedType
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override IList<CustomAttributeData> GetCustomAttributesData()
+        {
+            var attrs = new List<CustomAttributeData>();
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderXmlDocAttribute(string.Format("This is a synthetic *property* Localized!  ኤፍ ሻርፕ for {0}.{1}", this._DeclaringType.Namespace, this._DeclaringType.Name))));
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderDefinitionLocationAttribute() { Column = 5, FilePath = "File.fs", Line = 3 }));
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderEditorHideMethodsAttribute()));
+            return attrs;
+        }
+    }
+}
diff --git a/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithLocalizedComment/ArtificialType.cs b/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithLocalizedComment/ArtificialType.cs
new file mode 100644
index 0000000..b454faa
--- /dev/null
+++ b/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithLocalizedComment/ArtificialType.cs
@@ -0,0 +1,767 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Reflection;
+using Microsoft.FSharp.Core.CompilerServices;
+
+namespace TypeProviderInCSharp
+{
+    public class ArtificialType : Type
+    {
+        string _Namespace;
+        string _Name;
+        bool _IsGenericType;
+        bool _IsValueType;  // value type = not class / not interface
+        bool _IsByRef;      // is the value passed by reference?
+        bool _IsEnum;
+        bool _IsPointer;
+
+        Type _BaseType;
+        MethodInfo _Method1;
+        PropertyInfo _Property1;
+        EventInfo _Event1;
+        FieldInfo _Field1;
+        ConstructorInfo _Ctor1;
+
+        public ArtificialType(string @namespace, string name, bool isGenericType, Type basetype, bool isValueType, bool isByRef, bool isEnum, bool IsPointer)
+        {
+            _Name = name;
+            _Namespace = @namespace;
+            _IsGenericType = isGenericType;
+            _BaseType = basetype;
+            _IsValueType = isValueType;
+            _IsByRef = isByRef;
+            _IsEnum = isEnum;
+            _IsPointer = IsPointer;
+            _Method1 = new ArtificialMethodInfo("M", this, typeof(int[]), MethodAttributes.Public | MethodAttributes.Static);
+            _Property1 = new ArtificialPropertyInfo("StaticProp", this, typeof(decimal), true, false);
+            _Event1 = new ArtificalEventInfo("Event1", this, typeof(EventHandler));
+            _Ctor1 = new ArtificialConstructorInfo(this, new ParameterInfo[] {} );  // parameter-less ctor
+        }
+
+        public override System.Reflection.Assembly Assembly
+        {
+            get 
+            { 
+                
+                return Assembly.GetExecutingAssembly();
+            }
+        }
+
+        public override string Name
+        {
+            get 
+            { 
+                
+                return _Name;
+            }
+        }
+
+        public override Type BaseType
+        {
+            get
+            {
+                
+                return _BaseType;
+            }
+        }
+
+        public override string Namespace
+        {
+            get
+            {
+                
+                return _Namespace;
+            }
+        }
+
+        public override string FullName
+        {
+            get
+            { 
+                
+                return string.Format("{0}.{1}", _Namespace, _Name);
+            }
+        }
+
+        public override object[] GetCustomAttributes(Type attributeType, bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        public override object[] GetCustomAttributes(bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        // TODO: what is this?
+        protected override System.Reflection.TypeAttributes GetAttributeFlagsImpl()
+        {
+
+            return TypeAttributes.Class | TypeAttributes.Public | (TypeAttributes)0x40000000; // add the special flag to indicate an erased type, see TypeProviderTypeAttributes
+        }
+
+        // This one seems to be invoked when in IDE, I type something like:
+        // let _ = typeof<N.
+        // In this case => no constructors
+        public override System.Reflection.ConstructorInfo[] GetConstructors(System.Reflection.BindingFlags bindingAttr)
+        {
+            
+            // According to the spec, we should only expect these 4, so we guard against that here!
+            Debug.Assert(bindingAttr == (BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly), "bindingAttr has value not according to the spec!");
+            if (_Ctor1!=null) 
+                return new System.Reflection.ConstructorInfo[] { _Ctor1 };
+            else
+                return new System.Reflection.ConstructorInfo[] { };
+        }
+
+        // When you start typing more interesting things like...
+        // let a = N.T.M()
+        // this one gets invoked...
+        public override System.Reflection.MethodInfo[] GetMethods(System.Reflection.BindingFlags bindingAttr)
+        {
+            
+            // According to the spec, we should only expect these 4, so we guard against that here!
+            Debug.Assert(bindingAttr == (BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly), "bindingAttr has value not according to the spec!");
+            return new[] { _Method1 };
+        }
+
+        // This method is called when in the source file we have something like:
+        // - N.T.StaticProp 
+        // (most likely also when we have an instance prop...)
+        // name -> "StaticProp"
+        protected override System.Reflection.PropertyInfo GetPropertyImpl(string name, System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder binder, Type returnType, Type[] types, System.Reflection.ParameterModifier[] modifiers)
+        {
+            
+            // According to the spec, we should only expect these 4, so we guard against that here!
+            Debug.Assert(bindingAttr == (BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly), "bindingAttr has value not according to the spec!");
+            Debug.Assert(binder == null && returnType == null && types == null && modifiers == null, "One of binder, returnType, types, or modifiers was not null");
+            if (name == _Property1.Name)
+                return _Property1;
+            else
+                return null;
+        }
+
+        // Advertise our property...
+        // I think that is this one returns an empty array => you don't get intellisense/autocomplete in IDE/FSI
+        public override System.Reflection.PropertyInfo[] GetProperties(System.Reflection.BindingFlags bindingAttr)
+        {
+            
+            // According to the spec, we should only expect these 4, so we guard against that here!
+            Debug.Assert(bindingAttr == (BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly), "bindingAttr has value not according to the spec!");
+            return new PropertyInfo[] { _Property1 };
+        }
+
+        // No fields...
+        public override System.Reflection.FieldInfo GetField(string name, System.Reflection.BindingFlags bindingAttr)
+        {
+            
+            // According to the spec, we should only expect these 4, so we guard against that here!
+            Debug.Assert(bindingAttr == (BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly), "bindingAttr has value not according to the spec!");
+            return null;
+        }
+
+        public override System.Reflection.FieldInfo[] GetFields(System.Reflection.BindingFlags bindingAttr)
+        {
+            
+            // According to the spec, we should only expect these 4, so we guard against that here!
+            Debug.Assert(bindingAttr == (BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly), "bindingAttr has value not according to the spec!");
+            return new System.Reflection.FieldInfo[] { };
+        }
+
+        // Events
+        public override System.Reflection.EventInfo GetEvent(string name, System.Reflection.BindingFlags bindingAttr)
+        {
+            
+            // According to the spec, we should only expect these 4, so we guard against that here!
+            Debug.Assert(bindingAttr == (BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly), "bindingAttr has value not according to the spec!");
+            if (_Event1 != null && _Event1.Name == name)
+                return _Event1;
+            else
+                return null;
+        }
+
+        // Events...
+        public override System.Reflection.EventInfo[] GetEvents(System.Reflection.BindingFlags bindingAttr)
+        {
+            
+            return _Event1 != null ? new [] { _Event1 } : new System.Reflection.EventInfo[] { };
+        }
+
+        // TODO: according to the spec, this should not be invoked... instead it seems like it may be invoked...
+        //       ?? I have no idea what this is used for... ??
+        public override Type UnderlyingSystemType
+        {
+            get
+            {
+                
+                return null;
+            }
+        }
+
+        // According to the spec, this should always be 'false'
+        protected override bool IsArrayImpl()
+        {
+            
+            return false;    
+        }
+
+        // No interfaces...
+        public override Type[] GetInterfaces()
+        {
+            
+            return new Type[] { };
+        }
+
+        // No nested type
+        // This method is invoked on the type 'T', e.g.:
+        //    let _ = N.T.M
+        // to figure out if M is a nested type.
+        public override Type GetNestedType(string name, System.Reflection.BindingFlags bindingAttr)
+        {
+            
+            return null;
+        }
+        public override Type[] GetNestedTypes(System.Reflection.BindingFlags bindingAttr)
+        {
+            
+            // According to the spec, we should only expect these 4, so we guard against that here!
+            Debug.Assert(bindingAttr == (BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly), "bindingAttr has value not according to the spec!");
+            return new Type[] { };
+        }
+
+        // This one is invoked when the type has a .ctor 
+        // and the code looks like
+        // let _ = new N.T()
+        // for example.
+        // It was observed that the
+        // TODO: cover both cases!
+        public override bool IsGenericType
+        {
+            get
+            {
+                
+                return _IsGenericType;
+            }
+        }
+
+        // This is invoked if the IsGenericType is true
+        public override Type[] GetGenericArguments()
+        {
+            
+            if (_IsGenericType)
+                return new Type[] { typeof(int), typeof(decimal), typeof(System.Guid) };        // This is currently triggering an ICE...
+            else
+            {
+                Debug.Assert(false, "Why are we here?");
+                throw new NotImplementedException();
+            }
+
+        }
+
+        // This one seems to be invoked when compiling something like
+        // let a = new N.T()
+        // Let's just stay away from generics...
+        public override bool IsGenericTypeDefinition
+        {
+            get
+            {
+                
+                return _IsGenericType;
+            }
+        }
+
+        // This one seems to be invoked when compiling something like
+        // let a = new N.T()
+        // Let's just stay away from generics...
+        public override bool ContainsGenericParameters
+        {
+            get
+            {
+                
+                return _IsGenericType;
+            }
+        }
+
+        // This one seems to be checked when in IDE.
+        // let b = N.T(
+        protected override bool IsValueTypeImpl()
+        {
+            
+            return _IsValueType;
+        }
+
+        // This one seems to be checked when in IDE.
+        // let b = N.T(
+        protected override bool IsByRefImpl()
+        {
+            
+            return _IsByRef;
+        }
+
+        // This one seems to be checked when in IDE.
+        // let b = N.T(
+        public override bool IsEnum
+        {
+            get
+            {
+                
+                return _IsEnum;
+            }
+        }
+
+        // This one seems to be checked when in IDE.
+        // let b = N.T(
+        protected override bool IsPointerImpl()
+        {
+            
+            return _IsPointer;
+        }
+
+        public override string AssemblyQualifiedName
+        {
+            get 
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override Guid GUID
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        protected override System.Reflection.ConstructorInfo GetConstructorImpl(System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder binder, System.Reflection.CallingConventions callConvention, Type[] types, System.Reflection.ParameterModifier[] modifiers)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override Type GetElementType()
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override Type GetInterface(string name, bool ignoreCase)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override System.Reflection.MemberInfo[] GetMembers(System.Reflection.BindingFlags bindingAttr)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        protected override System.Reflection.MethodInfo GetMethodImpl(string name, System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder binder, System.Reflection.CallingConventions callConvention, Type[] types, System.Reflection.ParameterModifier[] modifiers)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        protected override bool HasElementTypeImpl()
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override object InvokeMember(string name, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, object target, object[] args, System.Reflection.ParameterModifier[] modifiers, System.Globalization.CultureInfo culture, string[] namedParameters)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        protected override bool IsCOMObjectImpl()
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        protected override bool IsPrimitiveImpl()
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override System.Reflection.Module Module
+        {
+            get {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override bool IsDefined(Type attributeType, bool inherit)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override MethodBase DeclaringMethod
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.DeclaringMethod;
+            }
+        }
+
+        // This one is invoked by the F# compiler!
+        public override Type DeclaringType
+        {
+            get
+            {
+                
+                return null; // base.DeclaringType;
+            }
+        }
+
+        public override Type[] FindInterfaces(TypeFilter filter, object filterCriteria)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.FindInterfaces(filter, filterCriteria);
+        }
+
+        public override MemberInfo[] FindMembers(MemberTypes memberType, BindingFlags bindingAttr, MemberFilter filter, object filterCriteria)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.FindMembers(memberType, bindingAttr, filter, filterCriteria);
+        }
+
+        public override GenericParameterAttributes GenericParameterAttributes
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.GenericParameterAttributes;
+            }
+        }
+
+        public override int GenericParameterPosition
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.GenericParameterPosition;
+            }
+        }
+
+        public override int GetArrayRank()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetArrayRank();
+        }
+
+        public override MemberInfo[] GetDefaultMembers()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetDefaultMembers();
+        }
+
+        public override string GetEnumName(object value)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetEnumName(value);
+        }
+
+        public override string[] GetEnumNames()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetEnumNames();
+        }
+
+        public override Type GetEnumUnderlyingType()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetEnumUnderlyingType();
+        }
+
+        public override Array GetEnumValues()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetEnumValues();
+        }
+
+        public override EventInfo[] GetEvents()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetEvents();
+        }
+
+        public override Type[] GetGenericParameterConstraints()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetGenericParameterConstraints();
+        }
+
+        public override Type GetGenericTypeDefinition()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetGenericTypeDefinition();
+        }
+
+        public override InterfaceMapping GetInterfaceMap(Type interfaceType)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetInterfaceMap(interfaceType);
+        }
+
+        public override MemberInfo[] GetMember(string name, BindingFlags bindingAttr)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetMember(name, bindingAttr);
+        }
+
+        public override MemberInfo[] GetMember(string name, MemberTypes type, BindingFlags bindingAttr)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetMember(name, type, bindingAttr);
+        }
+
+        protected override TypeCode GetTypeCodeImpl()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetTypeCodeImpl();
+        }
+
+        public override bool IsAssignableFrom(Type c)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.IsAssignableFrom(c);
+        }
+
+        protected override bool IsContextfulImpl()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.IsContextfulImpl();
+        }
+
+        public override bool IsEnumDefined(object value)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.IsEnumDefined(value);
+        }
+
+        public override bool IsEquivalentTo(Type other)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.IsEquivalentTo(other);
+        }
+
+        public override bool IsGenericParameter
+        {
+            get
+            {
+                return _IsGenericType;    
+            }
+        }
+
+        public override bool IsInstanceOfType(object o)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.IsInstanceOfType(o);
+        }
+
+        protected override bool IsMarshalByRefImpl()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.IsMarshalByRefImpl();
+        }
+
+        public override bool IsSecurityCritical
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.IsSecurityCritical;
+            }
+        }
+
+        public override bool IsSecuritySafeCritical
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.IsSecuritySafeCritical;
+            }
+        }
+
+        public override bool IsSecurityTransparent
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.IsSecurityTransparent;
+            }
+        }
+
+        public override bool IsSerializable
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.IsSerializable;
+            }
+        }
+
+        public override bool IsSubclassOf(Type c)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.IsSubclassOf(c);
+        }
+
+        public override Type MakeArrayType()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.MakeArrayType();
+        }
+
+        public override Type MakeArrayType(int rank)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.MakeArrayType(rank);
+        }
+
+        public override Type MakeByRefType()
+        {
+            return base.MakeByRefType();
+        }
+
+        public override Type MakeGenericType(params Type[] typeArguments)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.MakeGenericType(typeArguments);
+        }
+
+        public override Type MakePointerType()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.MakePointerType();
+        }
+
+        public override MemberTypes MemberType
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.MemberType;
+            }
+        }
+
+        public override int MetadataToken
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.MetadataToken;
+            }
+        }
+
+        public override Type ReflectedType
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.ReflectedType;
+            }
+        }
+
+        public override System.Runtime.InteropServices.StructLayoutAttribute StructLayoutAttribute
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.StructLayoutAttribute;
+            }
+        }
+
+        public override RuntimeTypeHandle TypeHandle
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.TypeHandle;
+            }
+        }
+
+        public override string ToString()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.ToString();
+        }
+
+        public override IList<CustomAttributeData> GetCustomAttributesData()
+        {
+            var attrs = new List<CustomAttributeData>();
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderXmlDocAttribute("This is a synthetic type Localized!  ኤፍ ሻርፕ")));
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderDefinitionLocationAttribute() { Column = 21, FilePath = "File.fs", Line = 3 }));
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderEditorHideMethodsAttribute()));
+            return attrs;
+        }
+    }
+}
diff --git a/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithLocalizedComment/TypeProviderInCSharp.cs b/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithLocalizedComment/TypeProviderInCSharp.cs
new file mode 100644
index 0000000..e4c569b
--- /dev/null
+++ b/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithLocalizedComment/TypeProviderInCSharp.cs
@@ -0,0 +1,150 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Microsoft.FSharp.Core.CompilerServices;
+using Microsoft.FSharp.Quotations;
+using System.Reflection;
+using System.Diagnostics;
+
+[assembly: TypeProviderAssembly()]
+
+namespace TypeProviderInCSharp
+{
+    //namespace N
+    //{
+    //    class S
+    //    {
+    //        public int instanceField;
+    //        public S(int x)
+    //        {
+    //            instanceField = x;
+    //        }
+    //    }
+    //}
+
+    class Namespace1 : IProvidedNamespace
+    {
+        const string _Namespace = "N";
+        const string _Name = "T";
+
+        // Type myType = new myType(typeof(N.S), "Bad.Name", typeof(Action), true);
+        Type myType = new ArtificialType(_Namespace, _Name, false, basetype: typeof(object), isValueType: false, isByRef: false, isEnum: false, IsPointer: false);
+
+        public IProvidedNamespace[] GetNestedNamespaces()
+        {
+
+            return new IProvidedNamespace[] { };
+        }
+
+        public Type[] GetTypes()
+        {
+
+            return new Type[] { myType };
+        }
+
+        public string NamespaceName
+        {
+            get { return _Namespace; }
+        }
+
+        public Type ResolveTypeName(string typeName)
+        {
+
+            if (typeName == _Name)
+            {
+                return myType;
+            }
+            return null;
+        }
+    }
+
+    [TypeProvider()]
+    public class TypeProvider : ITypeProvider
+    {
+        void IDisposable.Dispose()
+        {
+        }
+        private void Param(int staticParam)
+        {
+        }
+
+        public Type ApplyStaticArguments(Type typeWithoutArguments, string[] typeNameWithArguments, object[] staticArguments)
+        {
+            //Console.WriteLine("Hello from ApplyStaticArguments");
+            //var n = new myType(typeof(N.S), "S,\"1\"", typeof(object), false);
+            //return n;
+
+            return null;
+        }
+
+        public FSharpExpr GetInvokerExpression(System.Reflection.MethodBase syntheticMethodBase, FSharpExpr[] parameters)
+        {
+
+            if (syntheticMethodBase is System.Reflection.ConstructorInfo)
+            {
+                var ac = syntheticMethodBase as ArtificialConstructorInfo;
+                if (ac.DeclaringType.FullName == "N.T")
+                {
+                    return FSharpExpr.DefaultValue(ac.DeclaringType.BaseType);
+                }
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+            else if (syntheticMethodBase is System.Reflection.MethodInfo)
+            {
+                var am = syntheticMethodBase as ArtificialMethodInfo;
+                if (am.DeclaringType.FullName == "N.T" && am.Name == "M")
+                {
+                    return FSharpExpr.Lambda(FSharpVar.Global("", typeof(int[])), FSharpExpr.Value<int[]>(new[] { 1, 2, 3 }));
+                }
+                else if (am.DeclaringType.FullName == "N.T" && am.Name == "get_StaticProp")
+                {
+                    return FSharpExpr.Lambda(FSharpVar.Global("", typeof(decimal)), FSharpExpr.Value<decimal>(4.2M));
+                }
+                else if (am.DeclaringType.FullName == "N.T" && am.Name == "add_Event1")
+                {
+                    // Dummy expr... since we do not care about what it really does...
+                    return FSharpExpr.Lambda(FSharpVar.Global("", typeof(int)), FSharpExpr.Value<int>(1));
+                }
+                else if (am.DeclaringType.FullName == "N.T" && am.Name == "remove_Event1")
+                {
+                    // Dummy expr... since we do not care about what it really does...
+                    return FSharpExpr.Lambda(FSharpVar.Global("", typeof(int)), FSharpExpr.Value<int>(1));
+                }
+                else
+                {
+                    Debug.Assert(false, "NYI");
+                    throw new NotImplementedException();
+                }
+            }
+            else
+            {
+                Debug.Assert(false, "GetInvokerExpression() invoked with neither ConstructorInfo nor MethodInfo!");
+                return null;
+            }
+            //Expression<Func<S>> e = () => new S(9);
+            //return e.Body;
+
+            //throw new NotImplementedException();
+        }
+
+        public IProvidedNamespace[] GetNamespaces()
+        {
+
+            return new IProvidedNamespace[] { new Namespace1() };
+        }
+
+        public System.Reflection.ParameterInfo[] GetStaticParameters(Type typeWithoutArguments)
+        {
+
+            // No StaticParams
+            return new ParameterInfo[] { /* new myParameterInfo() */ };
+        }
+
+        public event EventHandler Invalidate;
+        public byte[] GetGeneratedAssemblyContents(Assembly assembly) { throw (new Exception("GetGeneratedAssemblyContents - only erased types were provided!!")); }
+    }
+}
diff --git a/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithLocalizedComment/XmlDocAttributeWithLocalizedComment.csproj b/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithLocalizedComment/XmlDocAttributeWithLocalizedComment.csproj
new file mode 100644
index 0000000..9813fb7
--- /dev/null
+++ b/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithLocalizedComment/XmlDocAttributeWithLocalizedComment.csproj
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information. -->
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <FSharpSourcesRoot>..\..\..\..\..\src</FSharpSourcesRoot>
+    <ProjectLanguage>CSharp</ProjectLanguage>
+  </PropertyGroup>
+  <Import Project="$(FSharpSourcesRoot)\FSharpSource.settings.targets" />
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{A559D7E8-7EFD-473A-B618-A10B41AB523B}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AssemblyName>XmlDocAttributeWithLocalizedComment</AssemblyName>
+    <WarningLevel>4</WarningLevel>
+    <NoWarn>0169;0067</NoWarn>
+    <DefineConstants>DEBUG;TRACE;$(DefineConstants)</DefineConstants>
+    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+    <OutputPath>$(FSharpSourcesRoot)\..\$(Configuration)\$(TargetFramework)\bin\UnitTestsResources\MockTypeProviders</OutputPath>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+    <ProjectReference Include="$(FSharpSourcesRoot)\fsharp\FSharp.Core\FSharp.Core.fsproj">
+      <Project>{DED3BBD7-53F4-428A-8C9F-27968E768605}</Project>
+      <Name>FSharp.Core</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="ArtificalEventInfo.cs" />
+    <Compile Include="ArtificialConstructorInfo.cs" />
+    <Compile Include="ArtificialMethodInfo.cs" />
+    <Compile Include="ArtificialParamInfo.cs" />
+    <Compile Include="ArtificialType.cs" />
+    <Compile Include="ArtificialPropertyInfo.cs" />
+    <Compile Include="TypeProviderInCSharp.cs" />
+    <Compile Include="..\Helpers.cs" />
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+</Project>
diff --git a/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithLongComment/ArtificalEventInfo.cs b/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithLongComment/ArtificalEventInfo.cs
new file mode 100644
index 0000000..e48426c
--- /dev/null
+++ b/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithLongComment/ArtificalEventInfo.cs
@@ -0,0 +1,129 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Reflection;
+using Microsoft.FSharp.Core.CompilerServices;
+
+namespace TypeProviderInCSharp
+{
+    class ArtificalEventInfo : EventInfo
+    {
+        string _Name;
+        Type _DeclaringType;
+        Type _EventHandleType;
+        MethodInfo _AddMethod;
+        MethodInfo _RemoveMethod;
+
+        public ArtificalEventInfo(string Name, Type DeclaringType, Type EventHandleType)
+        {
+            _Name = Name;
+            _DeclaringType = DeclaringType;
+            _EventHandleType = EventHandleType;
+
+            _AddMethod = new ArtificialMethodInfo("add_" + _Name, _DeclaringType, typeof(void), MethodAttributes.FamANDAssem | MethodAttributes.Family | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.Public);
+            _RemoveMethod = new ArtificialMethodInfo("remove_" + _Name, _DeclaringType, typeof(void), MethodAttributes.FamANDAssem | MethodAttributes.Family | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.Public);
+        }
+
+        // This one is invoked
+        public override Type EventHandlerType
+        {
+            get
+            {
+                
+                return _EventHandleType;
+            }
+        }
+
+        public override string Name
+        {
+            get 
+            { 
+                
+                return _Name;
+            }
+        }
+
+        public override Type DeclaringType
+        {
+            get
+            {
+                
+                return _DeclaringType;
+            }
+        }
+
+        // This one is needed
+        public override MethodInfo GetAddMethod(bool nonPublic)
+        {
+            
+            Debug.Assert(!nonPublic, "GetAddMethod() was called with nonPublic=true");
+            return _AddMethod;
+        }
+
+        // This one is needed
+        public override MethodInfo GetRemoveMethod(bool nonPublic)
+        {
+            
+            Debug.Assert(!nonPublic, "GetRemoveMethod() was called with nonPublic=true");
+            return _RemoveMethod;
+        }
+
+        public override object[] GetCustomAttributes(Type attributeType, bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        public override EventAttributes Attributes
+        {
+            get
+            {
+                
+                return EventAttributes.None;
+            }
+        }
+
+        public override MethodInfo GetRaiseMethod(bool nonPublic)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override object[] GetCustomAttributes(bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        public override bool IsDefined(Type attributeType, bool inherit)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override Type ReflectedType
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override IList<CustomAttributeData> GetCustomAttributesData()
+        {
+            var attrs = new List<CustomAttributeData>();
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderXmlDocAttribute(string.Format("This is a synthetic *event* created by me for {0}.{1}. Which is used to test the tool tip of the typeprovider Event to check if it shows the right message or not.!", this._DeclaringType.Namespace, this._DeclaringType.Name))));
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderDefinitionLocationAttribute() { Column = 21, FilePath = "File.fs", Line = 3 }));
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderEditorHideMethodsAttribute()));
+            return attrs;
+        }
+    }
+}
diff --git a/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithLongComment/ArtificialConstructorInfo.cs b/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithLongComment/ArtificialConstructorInfo.cs
new file mode 100644
index 0000000..6d4b363
--- /dev/null
+++ b/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithLongComment/ArtificialConstructorInfo.cs
@@ -0,0 +1,134 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Reflection;
+using Microsoft.FSharp.Core.CompilerServices;
+
+namespace TypeProviderInCSharp
+{
+    class ArtificialConstructorInfo : ConstructorInfo
+    {
+        Type _DeclaringType;
+        ParameterInfo[] _ParameterInfo;
+
+        public ArtificialConstructorInfo(Type DeclaringType, ParameterInfo[] ParamInfo)
+        {
+            _DeclaringType = DeclaringType;
+            _ParameterInfo = ParamInfo;
+        }
+
+        public override Type DeclaringType
+        {
+            get
+            {
+                
+                return _DeclaringType;
+            }
+        }
+
+        // This one is invoked
+        public override ParameterInfo[] GetParameters()
+        {
+            
+            return _ParameterInfo;
+        }
+
+        // This one is indeed invoked
+        // I believe we should always return ".ctor"
+        public override string Name
+        {
+            get
+            {
+                
+                return ".ctor";
+            }
+        }
+
+        // Does it matter what we return here?
+        // This property is definitely checked by the compiler in code like this:
+        // let _ = new N.T()
+        // I copied the attribute set from the .ctor of System.DateTime - the documentation on MSDN assumes that one is already familiar with
+        // what they mean (=totally useless, as often happens)
+        public override MethodAttributes Attributes
+        {
+            get
+            {
+                
+                return MethodAttributes.FamANDAssem | MethodAttributes.Family | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName;
+            }
+        }
+
+        public override object[] GetCustomAttributes(Type attributeType, bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        public override object Invoke(BindingFlags invokeAttr, Binder binder, object[] parameters, System.Globalization.CultureInfo culture)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override MethodImplAttributes GetMethodImplementationFlags()
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override object Invoke(object obj, BindingFlags invokeAttr, Binder binder, object[] parameters, System.Globalization.CultureInfo culture)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override RuntimeMethodHandle MethodHandle
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override object[] GetCustomAttributes(bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        public override bool IsDefined(Type attributeType, bool inherit)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override Type ReflectedType
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override IList<CustomAttributeData> GetCustomAttributesData()
+        {
+            var attrs = new List<CustomAttributeData>();
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderXmlDocAttribute(string.Format("This is a synthetic .ctor created by me for {0}.{1}. Which is used to test the tool tip of the typeprovider Constructor to check if it shows the right message or not.!", this._DeclaringType.Namespace, this._DeclaringType.Name))));
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderDefinitionLocationAttribute() { Column = 21, FilePath = "File.fs", Line = 3 }));
+            // attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderEditorHideMethodsAttribute()));
+            return attrs;
+        }
+    }
+}
diff --git a/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithLongComment/ArtificialMethodInfo.cs b/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithLongComment/ArtificialMethodInfo.cs
new file mode 100644
index 0000000..f38c98f
--- /dev/null
+++ b/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithLongComment/ArtificialMethodInfo.cs
@@ -0,0 +1,168 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Reflection;
+using Microsoft.FSharp.Core.CompilerServices;
+
+namespace TypeProviderInCSharp
+{
+    class ArtificialMethodInfo : MethodInfo
+    {
+        string _Name;
+        Type _DeclaringType;
+        Type _ReturnType;
+        MethodAttributes _MethodAttributes;
+
+        public ArtificialMethodInfo(string Name, Type DeclaringType, Type ReturnType, MethodAttributes MethodAttributes)
+        {
+            _Name = Name;
+            _DeclaringType = DeclaringType;
+            _ReturnType = ReturnType;
+            _MethodAttributes = MethodAttributes;
+        }
+
+        public override string Name
+        {
+            get 
+            { 
+                
+                return _Name;
+            }
+        }
+
+        public override Type DeclaringType
+        {
+            get
+            {
+                
+                return _DeclaringType;
+            }
+        }
+
+        // Make the method Public and Static - 
+        // TODO: should be configurable in the ctor...
+        public override MethodAttributes Attributes
+        {
+            get
+            {
+                
+                return _MethodAttributes;
+            }
+        }
+
+        // No params
+        // TODO: should be configurable in the ctor...
+        public override ParameterInfo[] GetParameters()
+        {
+            
+            return new ParameterInfo[] {  };
+        }
+
+        public override ParameterInfo ReturnParameter
+        {
+            get
+            {
+                //
+                //var retvalpi = new ArtificialParamInfo(typeof(List<>), true);
+                //return retvalpi;
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+
+            }
+        }
+
+        public override Type ReturnType
+        {
+            get
+            {
+                
+                return _ReturnType;
+            }
+        }
+
+        public override MethodInfo GetBaseDefinition()
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override ICustomAttributeProvider ReturnTypeCustomAttributes
+        {
+            get 
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override MethodImplAttributes GetMethodImplementationFlags()
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override object Invoke(object obj, BindingFlags invokeAttr, Binder binder, object[] parameters, System.Globalization.CultureInfo culture)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override RuntimeMethodHandle MethodHandle
+        {
+            get 
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override object[] GetCustomAttributes(Type attributeType, bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        public override object[] GetCustomAttributes(bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        public override bool IsDefined(Type attributeType, bool inherit)
+        {
+            
+            Debug.Assert(false, "NYI"); 
+            throw new NotImplementedException();
+        }
+
+        public override Type ReflectedType
+        {
+            get 
+            { 
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override IList<CustomAttributeData> GetCustomAttributesData()
+        {
+            var attrs = new List<CustomAttributeData>();
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderXmlDocAttribute("This is a synthetic *method* created by me!!. Which is used to test the tool tip of the typeprovider Method to check if it shows the right message or not.!")));
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderDefinitionLocationAttribute() { Column = 21, FilePath = "File.fs", Line = 3 }));
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderEditorHideMethodsAttribute()));
+            return attrs;
+        }
+
+    }
+}
diff --git a/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithLongComment/ArtificialParamInfo.cs b/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithLongComment/ArtificialParamInfo.cs
new file mode 100644
index 0000000..3d8d231
--- /dev/null
+++ b/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithLongComment/ArtificialParamInfo.cs
@@ -0,0 +1,154 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Reflection;
+using Microsoft.FSharp.Core.CompilerServices;
+
+namespace TypeProviderInCSharp
+{
+    public class ArtificialParamInfo : ParameterInfo
+    {
+        Type _type;
+        bool _isRetVal;
+
+        public ArtificialParamInfo(Type type, bool isRetVal)
+        {
+            _type = type;
+            _isRetVal = IsRetval;
+        }
+
+        // TODO: allow more customizations...
+        public override ParameterAttributes Attributes
+        {
+            get
+            {
+                return _isRetVal ? ParameterAttributes.Retval : ParameterAttributes.None;
+            }
+        }
+
+        public override Type ParameterType
+        {
+            get
+            {
+                return _type;
+            }
+        }
+
+        public override object DefaultValue
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override bool Equals(object obj)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override object[] GetCustomAttributes(bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        public override object[] GetCustomAttributes(Type attributeType, bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        public override int GetHashCode()
+        {
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override Type[] GetOptionalCustomModifiers()
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override Type[] GetRequiredCustomModifiers()
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override bool IsDefined(Type attributeType, bool inherit)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override MemberInfo Member
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override int MetadataToken
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override string Name
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override int Position
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override object RawDefaultValue
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override string ToString()
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+    }
+}
diff --git a/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithLongComment/ArtificialPropertyInfo.cs b/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithLongComment/ArtificialPropertyInfo.cs
new file mode 100644
index 0000000..172f4eb
--- /dev/null
+++ b/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithLongComment/ArtificialPropertyInfo.cs
@@ -0,0 +1,180 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Reflection;
+using Microsoft.FSharp.Core.CompilerServices;
+
+namespace TypeProviderInCSharp
+{
+    class ArtificialPropertyInfo : PropertyInfo
+    {
+        string _Name;
+        bool _CanRead;
+        bool _CanWrite;
+        Type _DeclaringType;
+        Type _PropertyType;
+
+        MethodInfo _GetMethod;
+        MethodInfo _SetMethod;
+
+        public ArtificialPropertyInfo(string Name, Type DeclaringType, Type PropertyType, bool CanRead, bool CanWrite)
+        {
+            _Name = Name;
+            _DeclaringType = DeclaringType;
+            _PropertyType = PropertyType;
+            _CanRead = CanRead;
+            _CanWrite = CanWrite;
+
+            if(CanRead)
+                _GetMethod = new ArtificialMethodInfo("get_" + _Name, _DeclaringType, _PropertyType, MethodAttributes.Public | MethodAttributes.Static);
+            if (CanWrite)
+                _SetMethod = new ArtificialMethodInfo("set_" + _Name, _DeclaringType, null /* ?? */, MethodAttributes.Public | MethodAttributes.Static);
+
+        }
+
+        // The name of this property...
+        public override string Name
+        {
+            get
+            {
+                
+                return _Name;
+            }
+        }
+
+        // Needed
+        public override bool CanRead
+        {
+            get
+            {
+                
+                return _CanRead;
+            }
+        }
+
+        // If CanRead is true, this one gets invoked.
+        public override MethodInfo GetGetMethod(bool nonPublic)
+        {
+            
+            Debug.Assert(!nonPublic, "GetGetMethod was invoked with nonPublic=true");
+            return _GetMethod;
+        }
+
+        // Why is this invoked?
+        public override ParameterInfo[] GetIndexParameters()
+        {
+            
+            return new ParameterInfo[] { /* new ArtificialParamInfo(typeof(int), isRetVal: false), new ArtificialParamInfo(typeof(decimal), isRetVal: false) */};
+        }
+
+        // If CanRead is false, this one gets invoked... without checking 'CanWrite' (?)
+        public override MethodInfo GetSetMethod(bool nonPublic)
+        {
+            
+            return _SetMethod;
+        }
+
+        public override bool CanWrite
+        {
+            get
+            {
+                
+                return _CanWrite;
+            }
+        }
+
+        // Interestingly enough, this one seems to be invoked only when I hover over the property in the IDE...
+        public override Type PropertyType
+        {
+            get
+            {
+                
+                return _PropertyType;
+            }
+        }
+
+        // Interestingly enough, this one seems to be invoked only when I hover over the property in the IDE...
+        public override Type DeclaringType
+        {
+            get
+            {
+                
+                return _DeclaringType;
+            }
+        }
+
+        public override object[] GetCustomAttributes(Type attributeType, bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+
+        public override PropertyAttributes Attributes
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override MethodInfo[] GetAccessors(bool nonPublic)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override object GetValue(object obj, BindingFlags invokeAttr, Binder binder, object[] index, System.Globalization.CultureInfo culture)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override void SetValue(object obj, object value, BindingFlags invokeAttr, Binder binder, object[] index, System.Globalization.CultureInfo culture)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override object[] GetCustomAttributes(bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        public override bool IsDefined(Type attributeType, bool inherit)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override Type ReflectedType
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override IList<CustomAttributeData> GetCustomAttributesData()
+        {
+            var attrs = new List<CustomAttributeData>();
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderXmlDocAttribute(string.Format("This is a synthetic *property* created by me for {0}.{1}. Which is used to test the tool tip of the typeprovider Property to check if it shows the right message or not.!", this._DeclaringType.Namespace, this._DeclaringType.Name))));
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderDefinitionLocationAttribute() { Column = 21, FilePath = "File.fs", Line = 3 }));
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderEditorHideMethodsAttribute()));
+            return attrs;
+        }
+    }
+}
diff --git a/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithLongComment/ArtificialType.cs b/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithLongComment/ArtificialType.cs
new file mode 100644
index 0000000..d017244
--- /dev/null
+++ b/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithLongComment/ArtificialType.cs
@@ -0,0 +1,767 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Reflection;
+using Microsoft.FSharp.Core.CompilerServices;
+
+namespace TypeProviderInCSharp
+{
+    public class ArtificialType : Type
+    {
+        string _Namespace;
+        string _Name;
+        bool _IsGenericType;
+        bool _IsValueType;  // value type = not class / not interface
+        bool _IsByRef;      // is the value passed by reference?
+        bool _IsEnum;
+        bool _IsPointer;
+
+        Type _BaseType;
+        MethodInfo _Method1;
+        PropertyInfo _Property1;
+        EventInfo _Event1;
+        FieldInfo _Field1;
+        ConstructorInfo _Ctor1;
+
+        public ArtificialType(string @namespace, string name, bool isGenericType, Type basetype, bool isValueType, bool isByRef, bool isEnum, bool IsPointer)
+        {
+            _Name = name;
+            _Namespace = @namespace;
+            _IsGenericType = isGenericType;
+            _BaseType = basetype;
+            _IsValueType = isValueType;
+            _IsByRef = isByRef;
+            _IsEnum = isEnum;
+            _IsPointer = IsPointer;
+            _Method1 = new ArtificialMethodInfo("M", this, typeof(int[]), MethodAttributes.Public | MethodAttributes.Static);
+            _Property1 = new ArtificialPropertyInfo("StaticProp", this, typeof(decimal), true, false);
+            _Event1 = new ArtificalEventInfo("Event1", this, typeof(EventHandler));
+            _Ctor1 = new ArtificialConstructorInfo(this, new ParameterInfo[] {} );  // parameter-less ctor
+        }
+
+        public override System.Reflection.Assembly Assembly
+        {
+            get 
+            { 
+                
+                return Assembly.GetExecutingAssembly();
+            }
+        }
+
+        public override string Name
+        {
+            get 
+            { 
+                
+                return _Name;
+            }
+        }
+
+        public override Type BaseType
+        {
+            get
+            {
+                
+                return _BaseType;
+            }
+        }
+
+        public override string Namespace
+        {
+            get
+            {
+                
+                return _Namespace;
+            }
+        }
+
+        public override string FullName
+        {
+            get
+            { 
+                
+                return string.Format("{0}.{1}", _Namespace, _Name);
+            }
+        }
+
+        public override object[] GetCustomAttributes(Type attributeType, bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        public override object[] GetCustomAttributes(bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        // TODO: what is this?
+        protected override System.Reflection.TypeAttributes GetAttributeFlagsImpl()
+        {
+
+            return TypeAttributes.Class | TypeAttributes.Public | (TypeAttributes)0x40000000; // add the special flag to indicate an erased type, see TypeProviderTypeAttributes
+        }
+
+        // This one seems to be invoked when in IDE, I type something like:
+        // let _ = typeof<N.
+        // In this case => no constructors
+        public override System.Reflection.ConstructorInfo[] GetConstructors(System.Reflection.BindingFlags bindingAttr)
+        {
+            
+            // According to the spec, we should only expect these 4, so we guard against that here!
+            Debug.Assert(bindingAttr == (BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly), "bindingAttr has value not according to the spec!");
+            if (_Ctor1!=null) 
+                return new System.Reflection.ConstructorInfo[] { _Ctor1 };
+            else
+                return new System.Reflection.ConstructorInfo[] { };
+        }
+
+        // When you start typing more interesting things like...
+        // let a = N.T.M()
+        // this one gets invoked...
+        public override System.Reflection.MethodInfo[] GetMethods(System.Reflection.BindingFlags bindingAttr)
+        {
+            
+            // According to the spec, we should only expect these 4, so we guard against that here!
+            Debug.Assert(bindingAttr == (BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly), "bindingAttr has value not according to the spec!");
+            return new[] { _Method1 };
+        }
+
+        // This method is called when in the source file we have something like:
+        // - N.T.StaticProp 
+        // (most likely also when we have an instance prop...)
+        // name -> "StaticProp"
+        protected override System.Reflection.PropertyInfo GetPropertyImpl(string name, System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder binder, Type returnType, Type[] types, System.Reflection.ParameterModifier[] modifiers)
+        {
+            
+            // According to the spec, we should only expect these 4, so we guard against that here!
+            Debug.Assert(bindingAttr == (BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly), "bindingAttr has value not according to the spec!");
+            Debug.Assert(binder == null && returnType == null && types == null && modifiers == null, "One of binder, returnType, types, or modifiers was not null");
+            if (name == _Property1.Name)
+                return _Property1;
+            else
+                return null;
+        }
+
+        // Advertise our property...
+        // I think that is this one returns an empty array => you don't get intellisense/autocomplete in IDE/FSI
+        public override System.Reflection.PropertyInfo[] GetProperties(System.Reflection.BindingFlags bindingAttr)
+        {
+            
+            // According to the spec, we should only expect these 4, so we guard against that here!
+            Debug.Assert(bindingAttr == (BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly), "bindingAttr has value not according to the spec!");
+            return new PropertyInfo[] { _Property1 };
+        }
+
+        // No fields...
+        public override System.Reflection.FieldInfo GetField(string name, System.Reflection.BindingFlags bindingAttr)
+        {
+            
+            // According to the spec, we should only expect these 4, so we guard against that here!
+            Debug.Assert(bindingAttr == (BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly), "bindingAttr has value not according to the spec!");
+            return null;
+        }
+
+        public override System.Reflection.FieldInfo[] GetFields(System.Reflection.BindingFlags bindingAttr)
+        {
+            
+            // According to the spec, we should only expect these 4, so we guard against that here!
+            Debug.Assert(bindingAttr == (BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly), "bindingAttr has value not according to the spec!");
+            return new System.Reflection.FieldInfo[] { };
+        }
+
+        // Events
+        public override System.Reflection.EventInfo GetEvent(string name, System.Reflection.BindingFlags bindingAttr)
+        {
+            
+            // According to the spec, we should only expect these 4, so we guard against that here!
+            Debug.Assert(bindingAttr == (BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly), "bindingAttr has value not according to the spec!");
+            if (_Event1 != null && _Event1.Name == name)
+                return _Event1;
+            else
+                return null;
+        }
+
+        // Events...
+        public override System.Reflection.EventInfo[] GetEvents(System.Reflection.BindingFlags bindingAttr)
+        {
+            
+            return _Event1 != null ? new [] { _Event1 } : new System.Reflection.EventInfo[] { };
+        }
+
+        // TODO: according to the spec, this should not be invoked... instead it seems like it may be invoked...
+        //       ?? I have no idea what this is used for... ??
+        public override Type UnderlyingSystemType
+        {
+            get
+            {
+                
+                return null;
+            }
+        }
+
+        // According to the spec, this should always be 'false'
+        protected override bool IsArrayImpl()
+        {
+            
+            return false;    
+        }
+
+        // No interfaces...
+        public override Type[] GetInterfaces()
+        {
+            
+            return new Type[] { };
+        }
+
+        // No nested type
+        // This method is invoked on the type 'T', e.g.:
+        //    let _ = N.T.M
+        // to figure out if M is a nested type.
+        public override Type GetNestedType(string name, System.Reflection.BindingFlags bindingAttr)
+        {
+            
+            return null;
+        }
+        public override Type[] GetNestedTypes(System.Reflection.BindingFlags bindingAttr)
+        {
+            
+            // According to the spec, we should only expect these 4, so we guard against that here!
+            Debug.Assert(bindingAttr == (BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly), "bindingAttr has value not according to the spec!");
+            return new Type[] { };
+        }
+
+        // This one is invoked when the type has a .ctor 
+        // and the code looks like
+        // let _ = new N.T()
+        // for example.
+        // It was observed that the
+        // TODO: cover both cases!
+        public override bool IsGenericType
+        {
+            get
+            {
+                
+                return _IsGenericType;
+            }
+        }
+
+        // This is invoked if the IsGenericType is true
+        public override Type[] GetGenericArguments()
+        {
+            
+            if (_IsGenericType)
+                return new Type[] { typeof(int), typeof(decimal), typeof(System.Guid) };        // This is currently triggering an ICE...
+            else
+            {
+                Debug.Assert(false, "Why are we here?");
+                throw new NotImplementedException();
+            }
+
+        }
+
+        // This one seems to be invoked when compiling something like
+        // let a = new N.T()
+        // Let's just stay away from generics...
+        public override bool IsGenericTypeDefinition
+        {
+            get
+            {
+                
+                return _IsGenericType;
+            }
+        }
+
+        // This one seems to be invoked when compiling something like
+        // let a = new N.T()
+        // Let's just stay away from generics...
+        public override bool ContainsGenericParameters
+        {
+            get
+            {
+                
+                return _IsGenericType;
+            }
+        }
+
+        // This one seems to be checked when in IDE.
+        // let b = N.T(
+        protected override bool IsValueTypeImpl()
+        {
+            
+            return _IsValueType;
+        }
+
+        // This one seems to be checked when in IDE.
+        // let b = N.T(
+        protected override bool IsByRefImpl()
+        {
+            
+            return _IsByRef;
+        }
+
+        // This one seems to be checked when in IDE.
+        // let b = N.T(
+        public override bool IsEnum
+        {
+            get
+            {
+                
+                return _IsEnum;
+            }
+        }
+
+        // This one seems to be checked when in IDE.
+        // let b = N.T(
+        protected override bool IsPointerImpl()
+        {
+            
+            return _IsPointer;
+        }
+
+        public override string AssemblyQualifiedName
+        {
+            get 
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override Guid GUID
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        protected override System.Reflection.ConstructorInfo GetConstructorImpl(System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder binder, System.Reflection.CallingConventions callConvention, Type[] types, System.Reflection.ParameterModifier[] modifiers)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override Type GetElementType()
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override Type GetInterface(string name, bool ignoreCase)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override System.Reflection.MemberInfo[] GetMembers(System.Reflection.BindingFlags bindingAttr)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        protected override System.Reflection.MethodInfo GetMethodImpl(string name, System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder binder, System.Reflection.CallingConventions callConvention, Type[] types, System.Reflection.ParameterModifier[] modifiers)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        protected override bool HasElementTypeImpl()
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override object InvokeMember(string name, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, object target, object[] args, System.Reflection.ParameterModifier[] modifiers, System.Globalization.CultureInfo culture, string[] namedParameters)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        protected override bool IsCOMObjectImpl()
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        protected override bool IsPrimitiveImpl()
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override System.Reflection.Module Module
+        {
+            get {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override bool IsDefined(Type attributeType, bool inherit)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override MethodBase DeclaringMethod
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.DeclaringMethod;
+            }
+        }
+
+        // This one is invoked by the F# compiler!
+        public override Type DeclaringType
+        {
+            get
+            {
+                
+                return null; // base.DeclaringType;
+            }
+        }
+
+        public override Type[] FindInterfaces(TypeFilter filter, object filterCriteria)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.FindInterfaces(filter, filterCriteria);
+        }
+
+        public override MemberInfo[] FindMembers(MemberTypes memberType, BindingFlags bindingAttr, MemberFilter filter, object filterCriteria)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.FindMembers(memberType, bindingAttr, filter, filterCriteria);
+        }
+
+        public override GenericParameterAttributes GenericParameterAttributes
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.GenericParameterAttributes;
+            }
+        }
+
+        public override int GenericParameterPosition
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.GenericParameterPosition;
+            }
+        }
+
+        public override int GetArrayRank()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetArrayRank();
+        }
+
+        public override MemberInfo[] GetDefaultMembers()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetDefaultMembers();
+        }
+
+        public override string GetEnumName(object value)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetEnumName(value);
+        }
+
+        public override string[] GetEnumNames()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetEnumNames();
+        }
+
+        public override Type GetEnumUnderlyingType()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetEnumUnderlyingType();
+        }
+
+        public override Array GetEnumValues()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetEnumValues();
+        }
+
+        public override EventInfo[] GetEvents()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetEvents();
+        }
+
+        public override Type[] GetGenericParameterConstraints()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetGenericParameterConstraints();
+        }
+
+        public override Type GetGenericTypeDefinition()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetGenericTypeDefinition();
+        }
+
+        public override InterfaceMapping GetInterfaceMap(Type interfaceType)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetInterfaceMap(interfaceType);
+        }
+
+        public override MemberInfo[] GetMember(string name, BindingFlags bindingAttr)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetMember(name, bindingAttr);
+        }
+
+        public override MemberInfo[] GetMember(string name, MemberTypes type, BindingFlags bindingAttr)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetMember(name, type, bindingAttr);
+        }
+
+        protected override TypeCode GetTypeCodeImpl()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetTypeCodeImpl();
+        }
+
+        public override bool IsAssignableFrom(Type c)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.IsAssignableFrom(c);
+        }
+
+        protected override bool IsContextfulImpl()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.IsContextfulImpl();
+        }
+
+        public override bool IsEnumDefined(object value)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.IsEnumDefined(value);
+        }
+
+        public override bool IsEquivalentTo(Type other)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.IsEquivalentTo(other);
+        }
+
+        public override bool IsGenericParameter
+        {
+            get
+            {
+                return _IsGenericType;    
+            }
+        }
+
+        public override bool IsInstanceOfType(object o)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.IsInstanceOfType(o);
+        }
+
+        protected override bool IsMarshalByRefImpl()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.IsMarshalByRefImpl();
+        }
+
+        public override bool IsSecurityCritical
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.IsSecurityCritical;
+            }
+        }
+
+        public override bool IsSecuritySafeCritical
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.IsSecuritySafeCritical;
+            }
+        }
+
+        public override bool IsSecurityTransparent
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.IsSecurityTransparent;
+            }
+        }
+
+        public override bool IsSerializable
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.IsSerializable;
+            }
+        }
+
+        public override bool IsSubclassOf(Type c)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.IsSubclassOf(c);
+        }
+
+        public override Type MakeArrayType()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.MakeArrayType();
+        }
+
+        public override Type MakeArrayType(int rank)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.MakeArrayType(rank);
+        }
+
+        public override Type MakeByRefType()
+        {
+            return base.MakeByRefType();
+        }
+
+        public override Type MakeGenericType(params Type[] typeArguments)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.MakeGenericType(typeArguments);
+        }
+
+        public override Type MakePointerType()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.MakePointerType();
+        }
+
+        public override MemberTypes MemberType
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.MemberType;
+            }
+        }
+
+        public override int MetadataToken
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.MetadataToken;
+            }
+        }
+
+        public override Type ReflectedType
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.ReflectedType;
+            }
+        }
+
+        public override System.Runtime.InteropServices.StructLayoutAttribute StructLayoutAttribute
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.StructLayoutAttribute;
+            }
+        }
+
+        public override RuntimeTypeHandle TypeHandle
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.TypeHandle;
+            }
+        }
+
+        public override string ToString()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.ToString();
+        }
+
+        public override IList<CustomAttributeData> GetCustomAttributesData()
+        {
+            var attrs = new List<CustomAttributeData>();
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderXmlDocAttribute("This is a synthetic type created by me!. Which is used to test the tool tip of the typeprovider type to check if it shows the right message or not.")));
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderDefinitionLocationAttribute() { Column = 21, FilePath = "File.fs", Line = 3 }));
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderEditorHideMethodsAttribute()));
+            return attrs;
+        }
+    }
+}
diff --git a/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithLongComment/TypeProviderInCSharp.cs b/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithLongComment/TypeProviderInCSharp.cs
new file mode 100644
index 0000000..e4c569b
--- /dev/null
+++ b/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithLongComment/TypeProviderInCSharp.cs
@@ -0,0 +1,150 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Microsoft.FSharp.Core.CompilerServices;
+using Microsoft.FSharp.Quotations;
+using System.Reflection;
+using System.Diagnostics;
+
+[assembly: TypeProviderAssembly()]
+
+namespace TypeProviderInCSharp
+{
+    //namespace N
+    //{
+    //    class S
+    //    {
+    //        public int instanceField;
+    //        public S(int x)
+    //        {
+    //            instanceField = x;
+    //        }
+    //    }
+    //}
+
+    class Namespace1 : IProvidedNamespace
+    {
+        const string _Namespace = "N";
+        const string _Name = "T";
+
+        // Type myType = new myType(typeof(N.S), "Bad.Name", typeof(Action), true);
+        Type myType = new ArtificialType(_Namespace, _Name, false, basetype: typeof(object), isValueType: false, isByRef: false, isEnum: false, IsPointer: false);
+
+        public IProvidedNamespace[] GetNestedNamespaces()
+        {
+
+            return new IProvidedNamespace[] { };
+        }
+
+        public Type[] GetTypes()
+        {
+
+            return new Type[] { myType };
+        }
+
+        public string NamespaceName
+        {
+            get { return _Namespace; }
+        }
+
+        public Type ResolveTypeName(string typeName)
+        {
+
+            if (typeName == _Name)
+            {
+                return myType;
+            }
+            return null;
+        }
+    }
+
+    [TypeProvider()]
+    public class TypeProvider : ITypeProvider
+    {
+        void IDisposable.Dispose()
+        {
+        }
+        private void Param(int staticParam)
+        {
+        }
+
+        public Type ApplyStaticArguments(Type typeWithoutArguments, string[] typeNameWithArguments, object[] staticArguments)
+        {
+            //Console.WriteLine("Hello from ApplyStaticArguments");
+            //var n = new myType(typeof(N.S), "S,\"1\"", typeof(object), false);
+            //return n;
+
+            return null;
+        }
+
+        public FSharpExpr GetInvokerExpression(System.Reflection.MethodBase syntheticMethodBase, FSharpExpr[] parameters)
+        {
+
+            if (syntheticMethodBase is System.Reflection.ConstructorInfo)
+            {
+                var ac = syntheticMethodBase as ArtificialConstructorInfo;
+                if (ac.DeclaringType.FullName == "N.T")
+                {
+                    return FSharpExpr.DefaultValue(ac.DeclaringType.BaseType);
+                }
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+            else if (syntheticMethodBase is System.Reflection.MethodInfo)
+            {
+                var am = syntheticMethodBase as ArtificialMethodInfo;
+                if (am.DeclaringType.FullName == "N.T" && am.Name == "M")
+                {
+                    return FSharpExpr.Lambda(FSharpVar.Global("", typeof(int[])), FSharpExpr.Value<int[]>(new[] { 1, 2, 3 }));
+                }
+                else if (am.DeclaringType.FullName == "N.T" && am.Name == "get_StaticProp")
+                {
+                    return FSharpExpr.Lambda(FSharpVar.Global("", typeof(decimal)), FSharpExpr.Value<decimal>(4.2M));
+                }
+                else if (am.DeclaringType.FullName == "N.T" && am.Name == "add_Event1")
+                {
+                    // Dummy expr... since we do not care about what it really does...
+                    return FSharpExpr.Lambda(FSharpVar.Global("", typeof(int)), FSharpExpr.Value<int>(1));
+                }
+                else if (am.DeclaringType.FullName == "N.T" && am.Name == "remove_Event1")
+                {
+                    // Dummy expr... since we do not care about what it really does...
+                    return FSharpExpr.Lambda(FSharpVar.Global("", typeof(int)), FSharpExpr.Value<int>(1));
+                }
+                else
+                {
+                    Debug.Assert(false, "NYI");
+                    throw new NotImplementedException();
+                }
+            }
+            else
+            {
+                Debug.Assert(false, "GetInvokerExpression() invoked with neither ConstructorInfo nor MethodInfo!");
+                return null;
+            }
+            //Expression<Func<S>> e = () => new S(9);
+            //return e.Body;
+
+            //throw new NotImplementedException();
+        }
+
+        public IProvidedNamespace[] GetNamespaces()
+        {
+
+            return new IProvidedNamespace[] { new Namespace1() };
+        }
+
+        public System.Reflection.ParameterInfo[] GetStaticParameters(Type typeWithoutArguments)
+        {
+
+            // No StaticParams
+            return new ParameterInfo[] { /* new myParameterInfo() */ };
+        }
+
+        public event EventHandler Invalidate;
+        public byte[] GetGeneratedAssemblyContents(Assembly assembly) { throw (new Exception("GetGeneratedAssemblyContents - only erased types were provided!!")); }
+    }
+}
diff --git a/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithLongComment/XmlDocAttributeWithLongComment.csproj b/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithLongComment/XmlDocAttributeWithLongComment.csproj
new file mode 100644
index 0000000..1fd6984
--- /dev/null
+++ b/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithLongComment/XmlDocAttributeWithLongComment.csproj
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information. -->
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <FSharpSourcesRoot>..\..\..\..\..\src</FSharpSourcesRoot>
+    <ProjectLanguage>CSharp</ProjectLanguage>
+  </PropertyGroup>
+  <Import Project="$(FSharpSourcesRoot)\FSharpSource.settings.targets" />
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{AC85EE6D-033C-45F9-B8BA-884BC22EC6D9}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AssemblyName>XmlDocAttributeWithLongComment</AssemblyName>
+    <WarningLevel>4</WarningLevel>
+    <NoWarn>0169;0067</NoWarn>
+    <DefineConstants>DEBUG;TRACE;$(DefineConstants)</DefineConstants>
+    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+    <OutputPath>$(FSharpSourcesRoot)\..\$(Configuration)\$(TargetFramework)\bin\UnitTestsResources\MockTypeProviders</OutputPath>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+    <ProjectReference Include="$(FSharpSourcesRoot)\fsharp\FSharp.Core\FSharp.Core.fsproj">
+      <Project>{DED3BBD7-53F4-428A-8C9F-27968E768605}</Project>
+      <Name>FSharp.Core</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="ArtificalEventInfo.cs" />
+    <Compile Include="ArtificialConstructorInfo.cs" />
+    <Compile Include="ArtificialMethodInfo.cs" />
+    <Compile Include="ArtificialParamInfo.cs" />
+    <Compile Include="ArtificialType.cs" />
+    <Compile Include="ArtificialPropertyInfo.cs" />
+    <Compile Include="TypeProviderInCSharp.cs" />
+    <Compile Include="..\Helpers.cs" />
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+</Project>
diff --git a/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithNullComment/ArtificalEventInfo.cs b/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithNullComment/ArtificalEventInfo.cs
new file mode 100644
index 0000000..822fa9f
--- /dev/null
+++ b/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithNullComment/ArtificalEventInfo.cs
@@ -0,0 +1,129 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Reflection;
+using Microsoft.FSharp.Core.CompilerServices;
+
+namespace TypeProviderInCSharp
+{
+    class ArtificalEventInfo : EventInfo
+    {
+        string _Name;
+        Type _DeclaringType;
+        Type _EventHandleType;
+        MethodInfo _AddMethod;
+        MethodInfo _RemoveMethod;
+
+        public ArtificalEventInfo(string Name, Type DeclaringType, Type EventHandleType)
+        {
+            _Name = Name;
+            _DeclaringType = DeclaringType;
+            _EventHandleType = EventHandleType;
+
+            _AddMethod = new ArtificialMethodInfo("add_" + _Name, _DeclaringType, typeof(void), MethodAttributes.FamANDAssem | MethodAttributes.Family | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.Public);
+            _RemoveMethod = new ArtificialMethodInfo("remove_" + _Name, _DeclaringType, typeof(void), MethodAttributes.FamANDAssem | MethodAttributes.Family | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.Public);
+        }
+
+        // This one is invoked
+        public override Type EventHandlerType
+        {
+            get
+            {
+                
+                return _EventHandleType;
+            }
+        }
+
+        public override string Name
+        {
+            get 
+            { 
+                
+                return _Name;
+            }
+        }
+
+        public override Type DeclaringType
+        {
+            get
+            {
+                
+                return _DeclaringType;
+            }
+        }
+
+        // This one is needed
+        public override MethodInfo GetAddMethod(bool nonPublic)
+        {
+            
+            Debug.Assert(!nonPublic, "GetAddMethod() was called with nonPublic=true");
+            return _AddMethod;
+        }
+
+        // This one is needed
+        public override MethodInfo GetRemoveMethod(bool nonPublic)
+        {
+            
+            Debug.Assert(!nonPublic, "GetRemoveMethod() was called with nonPublic=true");
+            return _RemoveMethod;
+        }
+
+        public override object[] GetCustomAttributes(Type attributeType, bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        public override EventAttributes Attributes
+        {
+            get
+            {
+                
+                return EventAttributes.None;
+            }
+        }
+
+        public override MethodInfo GetRaiseMethod(bool nonPublic)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override object[] GetCustomAttributes(bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        public override bool IsDefined(Type attributeType, bool inherit)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override Type ReflectedType
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override IList<CustomAttributeData> GetCustomAttributesData()
+        {
+            var attrs = new List<CustomAttributeData>();
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderXmlDocAttribute(null)));
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderDefinitionLocationAttribute() { Column = 21, FilePath = "File.fs", Line = 3 }));
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderEditorHideMethodsAttribute()));
+            return attrs;
+        }
+    }
+}
diff --git a/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithNullComment/ArtificialConstructorInfo.cs b/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithNullComment/ArtificialConstructorInfo.cs
new file mode 100644
index 0000000..c9264a6
--- /dev/null
+++ b/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithNullComment/ArtificialConstructorInfo.cs
@@ -0,0 +1,135 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Reflection;
+using Microsoft.FSharp.Core.CompilerServices;
+
+namespace TypeProviderInCSharp
+{
+    class ArtificialConstructorInfo : ConstructorInfo
+    {
+        Type _DeclaringType;
+        ParameterInfo[] _ParameterInfo;
+
+        public ArtificialConstructorInfo(Type DeclaringType, ParameterInfo[] ParamInfo)
+        {
+            _DeclaringType = DeclaringType;
+            _ParameterInfo = ParamInfo;
+        }
+
+        public override Type DeclaringType
+        {
+            get
+            {
+                
+                return _DeclaringType;
+            }
+        }
+
+        // This one is invoked
+        public override ParameterInfo[] GetParameters()
+        {
+            
+            return _ParameterInfo;
+        }
+
+        // This one is indeed invoked
+        // I believe we should always return ".ctor"
+        public override string Name
+        {
+            get
+            {
+                
+                return ".ctor";
+            }
+        }
+
+        // Does it matter what we return here?
+        // This property is definitely checked by the compiler in code like this:
+        // let _ = new N.T()
+        // I copied the attribute set from the .ctor of System.DateTime - the documentation on MSDN assumes that one is already familiar with
+        // what they mean (=totally useless, as often happens)
+        public override MethodAttributes Attributes
+        {
+            get
+            {
+                
+                return MethodAttributes.FamANDAssem | MethodAttributes.Family | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName;
+            }
+        }
+
+        public override object[] GetCustomAttributes(Type attributeType, bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        public override object Invoke(BindingFlags invokeAttr, Binder binder, object[] parameters, System.Globalization.CultureInfo culture)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override MethodImplAttributes GetMethodImplementationFlags()
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override object Invoke(object obj, BindingFlags invokeAttr, Binder binder, object[] parameters, System.Globalization.CultureInfo culture)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override RuntimeMethodHandle MethodHandle
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override object[] GetCustomAttributes(bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        public override bool IsDefined(Type attributeType, bool inherit)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override Type ReflectedType
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override IList<CustomAttributeData> GetCustomAttributesData()
+        {
+            var attrs = new List<CustomAttributeData>();
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderXmlDocAttribute(null)));
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderDefinitionLocationAttribute() { Column = 21, FilePath = "File.fs", Line = 3 }));
+            // attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderEditorHideMethodsAttribute()));
+            return attrs;
+        }
+
+    }
+}
diff --git a/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithNullComment/ArtificialMethodInfo.cs b/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithNullComment/ArtificialMethodInfo.cs
new file mode 100644
index 0000000..73e0a02
--- /dev/null
+++ b/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithNullComment/ArtificialMethodInfo.cs
@@ -0,0 +1,168 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Reflection;
+using Microsoft.FSharp.Core.CompilerServices;
+
+namespace TypeProviderInCSharp
+{
+    class ArtificialMethodInfo : MethodInfo
+    {
+        string _Name;
+        Type _DeclaringType;
+        Type _ReturnType;
+        MethodAttributes _MethodAttributes;
+
+        public ArtificialMethodInfo(string Name, Type DeclaringType, Type ReturnType, MethodAttributes MethodAttributes)
+        {
+            _Name = Name;
+            _DeclaringType = DeclaringType;
+            _ReturnType = ReturnType;
+            _MethodAttributes = MethodAttributes;
+        }
+
+        public override string Name
+        {
+            get 
+            { 
+                
+                return _Name;
+            }
+        }
+
+        public override Type DeclaringType
+        {
+            get
+            {
+                
+                return _DeclaringType;
+            }
+        }
+
+        // Make the method Public and Static - 
+        // TODO: should be configurable in the ctor...
+        public override MethodAttributes Attributes
+        {
+            get
+            {
+                
+                return _MethodAttributes;
+            }
+        }
+
+        // No params
+        // TODO: should be configurable in the ctor...
+        public override ParameterInfo[] GetParameters()
+        {
+            
+            return new ParameterInfo[] {  };
+        }
+
+        public override ParameterInfo ReturnParameter
+        {
+            get
+            {
+                //
+                //var retvalpi = new ArtificialParamInfo(typeof(List<>), true);
+                //return retvalpi;
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+
+            }
+        }
+
+        public override Type ReturnType
+        {
+            get
+            {
+                
+                return _ReturnType;
+            }
+        }
+
+        public override MethodInfo GetBaseDefinition()
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override ICustomAttributeProvider ReturnTypeCustomAttributes
+        {
+            get 
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override MethodImplAttributes GetMethodImplementationFlags()
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override object Invoke(object obj, BindingFlags invokeAttr, Binder binder, object[] parameters, System.Globalization.CultureInfo culture)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override RuntimeMethodHandle MethodHandle
+        {
+            get 
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override object[] GetCustomAttributes(Type attributeType, bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        public override object[] GetCustomAttributes(bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        public override bool IsDefined(Type attributeType, bool inherit)
+        {
+            
+            Debug.Assert(false, "NYI"); 
+            throw new NotImplementedException();
+        }
+
+        public override Type ReflectedType
+        {
+            get 
+            { 
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override IList<CustomAttributeData> GetCustomAttributesData()
+        {
+            var attrs = new List<CustomAttributeData>();
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderXmlDocAttribute(null)));
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderDefinitionLocationAttribute() { Column = 21, FilePath = "File.fs", Line = 3 }));
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderEditorHideMethodsAttribute()));
+            return attrs;
+        }
+
+    }
+}
diff --git a/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithNullComment/ArtificialParamInfo.cs b/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithNullComment/ArtificialParamInfo.cs
new file mode 100644
index 0000000..7c631b2
--- /dev/null
+++ b/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithNullComment/ArtificialParamInfo.cs
@@ -0,0 +1,155 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Reflection;
+using Microsoft.FSharp.Core.CompilerServices;
+
+namespace TypeProviderInCSharp
+{
+    public class ArtificialParamInfo : ParameterInfo
+    {
+        Type _type;
+        bool _isRetVal;
+
+        public ArtificialParamInfo(Type type, bool isRetVal)
+        {
+            _type = type;
+            _isRetVal = IsRetval;
+        }
+
+        // TODO: allow more customizations...
+        public override ParameterAttributes Attributes
+        {
+            get
+            {
+                return _isRetVal ? ParameterAttributes.Retval : ParameterAttributes.None;
+            }
+        }
+
+        public override Type ParameterType
+        {
+            get
+            {
+                return _type;
+            }
+        }
+
+        public override object DefaultValue
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override bool Equals(object obj)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override object[] GetCustomAttributes(bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        public override object[] GetCustomAttributes(Type attributeType, bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        public override int GetHashCode()
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override Type[] GetOptionalCustomModifiers()
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override Type[] GetRequiredCustomModifiers()
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override bool IsDefined(Type attributeType, bool inherit)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override MemberInfo Member
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override int MetadataToken
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override string Name
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override int Position
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override object RawDefaultValue
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override string ToString()
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+    }
+}
diff --git a/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithNullComment/ArtificialPropertyInfo.cs b/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithNullComment/ArtificialPropertyInfo.cs
new file mode 100644
index 0000000..2eb9727
--- /dev/null
+++ b/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithNullComment/ArtificialPropertyInfo.cs
@@ -0,0 +1,179 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Reflection;
+using Microsoft.FSharp.Core.CompilerServices;
+
+namespace TypeProviderInCSharp
+{
+    class ArtificialPropertyInfo : PropertyInfo
+    {
+        string _Name;
+        bool _CanRead;
+        bool _CanWrite;
+        Type _DeclaringType;
+        Type _PropertyType;
+
+        MethodInfo _GetMethod;
+        MethodInfo _SetMethod;
+
+        public ArtificialPropertyInfo(string Name, Type DeclaringType, Type PropertyType, bool CanRead, bool CanWrite)
+        {
+            _Name = Name;
+            _DeclaringType = DeclaringType;
+            _PropertyType = PropertyType;
+            _CanRead = CanRead;
+            _CanWrite = CanWrite;
+
+            if(CanRead)
+                _GetMethod = new ArtificialMethodInfo("get_" + _Name, _DeclaringType, _PropertyType, MethodAttributes.Public | MethodAttributes.Static);
+            if (CanWrite)
+                _SetMethod = new ArtificialMethodInfo("set_" + _Name, _DeclaringType, null /* ?? */, MethodAttributes.Public | MethodAttributes.Static);
+
+        }
+
+        // The name of this property...
+        public override string Name
+        {
+            get
+            {
+                
+                return _Name;
+            }
+        }
+
+        // Needed
+        public override bool CanRead
+        {
+            get
+            {
+                
+                return _CanRead;
+            }
+        }
+
+        // If CanRead is true, this one gets invoked.
+        public override MethodInfo GetGetMethod(bool nonPublic)
+        {
+            
+            Debug.Assert(!nonPublic, "GetGetMethod was invoked with nonPublic=true");
+            return _GetMethod;
+        }
+
+        // Why is this invoked?
+        public override ParameterInfo[] GetIndexParameters()
+        {
+            
+            return new ParameterInfo[] { /* new ArtificialParamInfo(typeof(int), isRetVal: false), new ArtificialParamInfo(typeof(decimal), isRetVal: false) */};
+        }
+
+        // If CanRead is false, this one gets invoked... without checking 'CanWrite' (?)
+        public override MethodInfo GetSetMethod(bool nonPublic)
+        {
+            
+            return _SetMethod;
+        }
+
+        public override bool CanWrite
+        {
+            get
+            {
+                
+                return _CanWrite;
+            }
+        }
+
+        // Interestingly enough, this one seems to be invoked only when I hover over the property in the IDE...
+        public override Type PropertyType
+        {
+            get
+            {
+                
+                return _PropertyType;
+            }
+        }
+
+        // Interestingly enough, this one seems to be invoked only when I hover over the property in the IDE...
+        public override Type DeclaringType
+        {
+            get
+            {
+                
+                return _DeclaringType;
+            }
+        }
+
+        public override object[] GetCustomAttributes(Type attributeType, bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        public override PropertyAttributes Attributes
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override MethodInfo[] GetAccessors(bool nonPublic)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override object GetValue(object obj, BindingFlags invokeAttr, Binder binder, object[] index, System.Globalization.CultureInfo culture)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override void SetValue(object obj, object value, BindingFlags invokeAttr, Binder binder, object[] index, System.Globalization.CultureInfo culture)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override object[] GetCustomAttributes(bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        public override bool IsDefined(Type attributeType, bool inherit)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override Type ReflectedType
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override IList<CustomAttributeData> GetCustomAttributesData()
+        {
+            var attrs = new List<CustomAttributeData>();
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderXmlDocAttribute(null)));
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderDefinitionLocationAttribute() { Column = 21, FilePath = "File.fs", Line = 3 }));
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderEditorHideMethodsAttribute()));
+            return attrs;
+        }
+    }
+}
diff --git a/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithNullComment/ArtificialType.cs b/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithNullComment/ArtificialType.cs
new file mode 100644
index 0000000..a54ba9d
--- /dev/null
+++ b/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithNullComment/ArtificialType.cs
@@ -0,0 +1,767 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Reflection;
+using Microsoft.FSharp.Core.CompilerServices;
+
+namespace TypeProviderInCSharp
+{
+    public class ArtificialType : Type
+    {
+        string _Namespace;
+        string _Name;
+        bool _IsGenericType;
+        bool _IsValueType;  // value type = not class / not interface
+        bool _IsByRef;      // is the value passed by reference?
+        bool _IsEnum;
+        bool _IsPointer;
+
+        Type _BaseType;
+        MethodInfo _Method1;
+        PropertyInfo _Property1;
+        EventInfo _Event1;
+        FieldInfo _Field1;
+        ConstructorInfo _Ctor1;
+
+        public ArtificialType(string @namespace, string name, bool isGenericType, Type basetype, bool isValueType, bool isByRef, bool isEnum, bool IsPointer)
+        {
+            _Name = name;
+            _Namespace = @namespace;
+            _IsGenericType = isGenericType;
+            _BaseType = basetype;
+            _IsValueType = isValueType;
+            _IsByRef = isByRef;
+            _IsEnum = isEnum;
+            _IsPointer = IsPointer;
+            _Method1 = new ArtificialMethodInfo("M", this, typeof(int[]), MethodAttributes.Public | MethodAttributes.Static);
+            _Property1 = new ArtificialPropertyInfo("StaticProp", this, typeof(decimal), true, false);
+            _Event1 = new ArtificalEventInfo("Event1", this, typeof(EventHandler));
+            _Ctor1 = new ArtificialConstructorInfo(this, new ParameterInfo[] {} );  // parameter-less ctor
+        }
+
+        public override System.Reflection.Assembly Assembly
+        {
+            get 
+            { 
+                
+                return Assembly.GetExecutingAssembly();
+            }
+        }
+
+        public override string Name
+        {
+            get 
+            { 
+                
+                return _Name;
+            }
+        }
+
+        public override Type BaseType
+        {
+            get
+            {
+                
+                return _BaseType;
+            }
+        }
+
+        public override string Namespace
+        {
+            get
+            {
+                
+                return _Namespace;
+            }
+        }
+
+        public override string FullName
+        {
+            get
+            { 
+                
+                return string.Format("{0}.{1}", _Namespace, _Name);
+            }
+        }
+
+        public override object[] GetCustomAttributes(Type attributeType, bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        public override object[] GetCustomAttributes(bool inherit)
+        {
+            Debug.Assert(false, "Why are we calling into GetCustomAttributes()?");
+            return null;
+        }
+
+        // TODO: what is this?
+        protected override System.Reflection.TypeAttributes GetAttributeFlagsImpl()
+        {
+
+            return TypeAttributes.Class | TypeAttributes.Public | (TypeAttributes)0x40000000; // add the special flag to indicate an erased type, see TypeProviderTypeAttributes
+        }
+
+        // This one seems to be invoked when in IDE, I type something like:
+        // let _ = typeof<N.
+        // In this case => no constructors
+        public override System.Reflection.ConstructorInfo[] GetConstructors(System.Reflection.BindingFlags bindingAttr)
+        {
+            
+            // According to the spec, we should only expect these 4, so we guard against that here!
+            Debug.Assert(bindingAttr == (BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly), "bindingAttr has value not according to the spec!");
+            if (_Ctor1!=null) 
+                return new System.Reflection.ConstructorInfo[] { _Ctor1 };
+            else
+                return new System.Reflection.ConstructorInfo[] { };
+        }
+
+        // When you start typing more interesting things like...
+        // let a = N.T.M()
+        // this one gets invoked...
+        public override System.Reflection.MethodInfo[] GetMethods(System.Reflection.BindingFlags bindingAttr)
+        {
+            
+            // According to the spec, we should only expect these 4, so we guard against that here!
+            Debug.Assert(bindingAttr == (BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly), "bindingAttr has value not according to the spec!");
+            return new[] { _Method1 };
+        }
+
+        // This method is called when in the source file we have something like:
+        // - N.T.StaticProp 
+        // (most likely also when we have an instance prop...)
+        // name -> "StaticProp"
+        protected override System.Reflection.PropertyInfo GetPropertyImpl(string name, System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder binder, Type returnType, Type[] types, System.Reflection.ParameterModifier[] modifiers)
+        {
+            
+            // According to the spec, we should only expect these 4, so we guard against that here!
+            Debug.Assert(bindingAttr == (BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly), "bindingAttr has value not according to the spec!");
+            Debug.Assert(binder == null && returnType == null && types == null && modifiers == null, "One of binder, returnType, types, or modifiers was not null");
+            if (name == _Property1.Name)
+                return _Property1;
+            else
+                return null;
+        }
+
+        // Advertise our property...
+        // I think that is this one returns an empty array => you don't get intellisense/autocomplete in IDE/FSI
+        public override System.Reflection.PropertyInfo[] GetProperties(System.Reflection.BindingFlags bindingAttr)
+        {
+            
+            // According to the spec, we should only expect these 4, so we guard against that here!
+            Debug.Assert(bindingAttr == (BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly), "bindingAttr has value not according to the spec!");
+            return new PropertyInfo[] { _Property1 };
+        }
+
+        // No fields...
+        public override System.Reflection.FieldInfo GetField(string name, System.Reflection.BindingFlags bindingAttr)
+        {
+            
+            // According to the spec, we should only expect these 4, so we guard against that here!
+            Debug.Assert(bindingAttr == (BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly), "bindingAttr has value not according to the spec!");
+            return null;
+        }
+
+        public override System.Reflection.FieldInfo[] GetFields(System.Reflection.BindingFlags bindingAttr)
+        {
+            
+            // According to the spec, we should only expect these 4, so we guard against that here!
+            Debug.Assert(bindingAttr == (BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly), "bindingAttr has value not according to the spec!");
+            return new System.Reflection.FieldInfo[] { };
+        }
+
+        // Events
+        public override System.Reflection.EventInfo GetEvent(string name, System.Reflection.BindingFlags bindingAttr)
+        {
+            
+            // According to the spec, we should only expect these 4, so we guard against that here!
+            Debug.Assert(bindingAttr == (BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly), "bindingAttr has value not according to the spec!");
+            if (_Event1 != null && _Event1.Name == name)
+                return _Event1;
+            else
+                return null;
+        }
+
+        // Events...
+        public override System.Reflection.EventInfo[] GetEvents(System.Reflection.BindingFlags bindingAttr)
+        {
+            
+            return _Event1 != null ? new [] { _Event1 } : new System.Reflection.EventInfo[] { };
+        }
+
+        // TODO: according to the spec, this should not be invoked... instead it seems like it may be invoked...
+        //       ?? I have no idea what this is used for... ??
+        public override Type UnderlyingSystemType
+        {
+            get
+            {
+                
+                return null;
+            }
+        }
+
+        // According to the spec, this should always be 'false'
+        protected override bool IsArrayImpl()
+        {
+            
+            return false;    
+        }
+
+        // No interfaces...
+        public override Type[] GetInterfaces()
+        {
+            
+            return new Type[] { };
+        }
+
+        // No nested type
+        // This method is invoked on the type 'T', e.g.:
+        //    let _ = N.T.M
+        // to figure out if M is a nested type.
+        public override Type GetNestedType(string name, System.Reflection.BindingFlags bindingAttr)
+        {
+            
+            return null;
+        }
+        public override Type[] GetNestedTypes(System.Reflection.BindingFlags bindingAttr)
+        {
+            
+            // According to the spec, we should only expect these 4, so we guard against that here!
+            Debug.Assert(bindingAttr == (BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly), "bindingAttr has value not according to the spec!");
+            return new Type[] { };
+        }
+
+        // This one is invoked when the type has a .ctor 
+        // and the code looks like
+        // let _ = new N.T()
+        // for example.
+        // It was observed that the
+        // TODO: cover both cases!
+        public override bool IsGenericType
+        {
+            get
+            {
+                
+                return _IsGenericType;
+            }
+        }
+
+        // This is invoked if the IsGenericType is true
+        public override Type[] GetGenericArguments()
+        {
+            
+            if (_IsGenericType)
+                return new Type[] { typeof(int), typeof(decimal), typeof(System.Guid) };        // This is currently triggering an ICE...
+            else
+            {
+                Debug.Assert(false, "Why are we here?");
+                throw new NotImplementedException();
+            }
+
+        }
+
+        // This one seems to be invoked when compiling something like
+        // let a = new N.T()
+        // Let's just stay away from generics...
+        public override bool IsGenericTypeDefinition
+        {
+            get
+            {
+                
+                return _IsGenericType;
+            }
+        }
+
+        // This one seems to be invoked when compiling something like
+        // let a = new N.T()
+        // Let's just stay away from generics...
+        public override bool ContainsGenericParameters
+        {
+            get
+            {
+                
+                return _IsGenericType;
+            }
+        }
+
+        // This one seems to be checked when in IDE.
+        // let b = N.T(
+        protected override bool IsValueTypeImpl()
+        {
+            
+            return _IsValueType;
+        }
+
+        // This one seems to be checked when in IDE.
+        // let b = N.T(
+        protected override bool IsByRefImpl()
+        {
+            
+            return _IsByRef;
+        }
+
+        // This one seems to be checked when in IDE.
+        // let b = N.T(
+        public override bool IsEnum
+        {
+            get
+            {
+                
+                return _IsEnum;
+            }
+        }
+
+        // This one seems to be checked when in IDE.
+        // let b = N.T(
+        protected override bool IsPointerImpl()
+        {
+            
+            return _IsPointer;
+        }
+
+        public override string AssemblyQualifiedName
+        {
+            get 
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override Guid GUID
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        protected override System.Reflection.ConstructorInfo GetConstructorImpl(System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder binder, System.Reflection.CallingConventions callConvention, Type[] types, System.Reflection.ParameterModifier[] modifiers)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override Type GetElementType()
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override Type GetInterface(string name, bool ignoreCase)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override System.Reflection.MemberInfo[] GetMembers(System.Reflection.BindingFlags bindingAttr)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        protected override System.Reflection.MethodInfo GetMethodImpl(string name, System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder binder, System.Reflection.CallingConventions callConvention, Type[] types, System.Reflection.ParameterModifier[] modifiers)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        protected override bool HasElementTypeImpl()
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override object InvokeMember(string name, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, object target, object[] args, System.Reflection.ParameterModifier[] modifiers, System.Globalization.CultureInfo culture, string[] namedParameters)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        protected override bool IsCOMObjectImpl()
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        protected override bool IsPrimitiveImpl()
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override System.Reflection.Module Module
+        {
+            get {
+                
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+        }
+
+        public override bool IsDefined(Type attributeType, bool inherit)
+        {
+            
+            Debug.Assert(false, "NYI");
+            throw new NotImplementedException();
+        }
+
+        public override MethodBase DeclaringMethod
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.DeclaringMethod;
+            }
+        }
+
+        // This one is invoked by the F# compiler!
+        public override Type DeclaringType
+        {
+            get
+            {
+                
+                return null; // base.DeclaringType;
+            }
+        }
+
+        public override Type[] FindInterfaces(TypeFilter filter, object filterCriteria)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.FindInterfaces(filter, filterCriteria);
+        }
+
+        public override MemberInfo[] FindMembers(MemberTypes memberType, BindingFlags bindingAttr, MemberFilter filter, object filterCriteria)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.FindMembers(memberType, bindingAttr, filter, filterCriteria);
+        }
+
+        public override GenericParameterAttributes GenericParameterAttributes
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.GenericParameterAttributes;
+            }
+        }
+
+        public override int GenericParameterPosition
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.GenericParameterPosition;
+            }
+        }
+
+        public override int GetArrayRank()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetArrayRank();
+        }
+
+        public override MemberInfo[] GetDefaultMembers()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetDefaultMembers();
+        }
+
+        public override string GetEnumName(object value)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetEnumName(value);
+        }
+
+        public override string[] GetEnumNames()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetEnumNames();
+        }
+
+        public override Type GetEnumUnderlyingType()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetEnumUnderlyingType();
+        }
+
+        public override Array GetEnumValues()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetEnumValues();
+        }
+
+        public override EventInfo[] GetEvents()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetEvents();
+        }
+
+        public override Type[] GetGenericParameterConstraints()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetGenericParameterConstraints();
+        }
+
+        public override Type GetGenericTypeDefinition()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetGenericTypeDefinition();
+        }
+
+        public override InterfaceMapping GetInterfaceMap(Type interfaceType)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetInterfaceMap(interfaceType);
+        }
+
+        public override MemberInfo[] GetMember(string name, BindingFlags bindingAttr)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetMember(name, bindingAttr);
+        }
+
+        public override MemberInfo[] GetMember(string name, MemberTypes type, BindingFlags bindingAttr)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetMember(name, type, bindingAttr);
+        }
+
+        protected override TypeCode GetTypeCodeImpl()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.GetTypeCodeImpl();
+        }
+
+        public override bool IsAssignableFrom(Type c)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.IsAssignableFrom(c);
+        }
+
+        protected override bool IsContextfulImpl()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.IsContextfulImpl();
+        }
+
+        public override bool IsEnumDefined(object value)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.IsEnumDefined(value);
+        }
+
+        public override bool IsEquivalentTo(Type other)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.IsEquivalentTo(other);
+        }
+
+        public override bool IsGenericParameter
+        {
+            get
+            {
+                return _IsGenericType;    
+            }
+        }
+
+        public override bool IsInstanceOfType(object o)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.IsInstanceOfType(o);
+        }
+
+        protected override bool IsMarshalByRefImpl()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.IsMarshalByRefImpl();
+        }
+
+        public override bool IsSecurityCritical
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.IsSecurityCritical;
+            }
+        }
+
+        public override bool IsSecuritySafeCritical
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.IsSecuritySafeCritical;
+            }
+        }
+
+        public override bool IsSecurityTransparent
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.IsSecurityTransparent;
+            }
+        }
+
+        public override bool IsSerializable
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.IsSerializable;
+            }
+        }
+
+        public override bool IsSubclassOf(Type c)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.IsSubclassOf(c);
+        }
+
+        public override Type MakeArrayType()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.MakeArrayType();
+        }
+
+        public override Type MakeArrayType(int rank)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.MakeArrayType(rank);
+        }
+
+        public override Type MakeByRefType()
+        {
+            return base.MakeByRefType();
+        }
+
+        public override Type MakeGenericType(params Type[] typeArguments)
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.MakeGenericType(typeArguments);
+        }
+
+        public override Type MakePointerType()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.MakePointerType();
+        }
+
+        public override MemberTypes MemberType
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.MemberType;
+            }
+        }
+
+        public override int MetadataToken
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.MetadataToken;
+            }
+        }
+
+        public override Type ReflectedType
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.ReflectedType;
+            }
+        }
+
+        public override System.Runtime.InteropServices.StructLayoutAttribute StructLayoutAttribute
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.StructLayoutAttribute;
+            }
+        }
+
+        public override RuntimeTypeHandle TypeHandle
+        {
+            get
+            {
+                
+                Debug.Assert(false, "NYI");
+                return base.TypeHandle;
+            }
+        }
+
+        public override string ToString()
+        {
+            
+            Debug.Assert(false, "NYI");
+            return base.ToString();
+        }
+
+        public override IList<CustomAttributeData> GetCustomAttributesData()
+        {
+            var attrs = new List<CustomAttributeData>();
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderXmlDocAttribute(null)));
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderDefinitionLocationAttribute() { Column = 21, FilePath = "File.fs", Line = 3 }));
+            attrs.Add(new Helpers.TypeProviderCustomAttributeData(new TypeProviderEditorHideMethodsAttribute()));
+            return attrs;
+        }
+    }
+}
diff --git a/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithNullComment/TypeProviderInCSharp.cs b/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithNullComment/TypeProviderInCSharp.cs
new file mode 100644
index 0000000..71cb069
--- /dev/null
+++ b/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithNullComment/TypeProviderInCSharp.cs
@@ -0,0 +1,150 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Microsoft.FSharp.Core.CompilerServices;
+using Microsoft.FSharp.Quotations;
+using System.Reflection;
+using System.Diagnostics;
+
+[assembly: TypeProviderAssembly()]
+
+namespace TypeProviderInCSharp
+{
+    //namespace N
+    //{
+    //    class S
+    //    {
+    //        public int instanceField;
+    //        public S(int x)
+    //        {
+    //            instanceField = x;
+    //        }
+    //    }
+    //}
+
+    class Namespace1 : IProvidedNamespace
+    {
+        const string _Namespace = "N";
+        const string _Name = "T";
+
+        // Type myType = new myType(typeof(N.S), "Bad.Name", typeof(Action), true);
+        Type myType = new ArtificialType(_Namespace, _Name, false, basetype: typeof(object), isValueType: false, isByRef: false, isEnum: false, IsPointer: false);
+
+        public IProvidedNamespace[] GetNestedNamespaces()
+        {
+
+            return new IProvidedNamespace[] { };
+        }
+
+        public Type[] GetTypes()
+        {
+
+            return new Type[] { myType };
+        }
+
+        public string NamespaceName
+        {
+            get { return _Namespace; }
+        }
+
+        public Type ResolveTypeName(string typeName)
+        {
+
+            if (typeName == _Name)
+            {
+                return myType;
+            }
+            return null;
+        }
+    }
+
+    [TypeProvider()]
+    public class TypeProvider : ITypeProvider
+    {
+        void IDisposable.Dispose()
+        {
+        }
+        private void Param(int staticParam)
+        {
+        }
+
+        public Type ApplyStaticArguments(Type typeWithoutArguments, string[] typeNameWithArguments, object[] staticArguments)
+        {
+            //Console.WriteLine("Hello from ApplyStaticArguments");
+            //var n = new myType(typeof(N.S), "S,\"1\"", typeof(object), false);
+            //return n;
+
+            return null;
+        }
+
+        public FSharpExpr GetInvokerExpression(System.Reflection.MethodBase syntheticMethodBase, FSharpExpr[] parameters)
+        {
+
+            if (syntheticMethodBase is System.Reflection.ConstructorInfo)
+            {
+                var ac = syntheticMethodBase as ArtificialConstructorInfo;
+                if (ac.DeclaringType.FullName == "N.T")
+                {
+                    return FSharpExpr.DefaultValue(ac.DeclaringType.BaseType);
+                }
+                Debug.Assert(false, "NYI");
+                throw new NotImplementedException();
+            }
+            else if (syntheticMethodBase is System.Reflection.MethodInfo)
+            {
+                var am = syntheticMethodBase as ArtificialMethodInfo;
+                if (am.DeclaringType.FullName == "N.T" && am.Name == "M")
+                {
+                    return FSharpExpr.Lambda(new FSharpVar("", typeof(int[]), null), FSharpExpr.Value<int[]>(new[] {1,2,3}));
+                }
+                else if (am.DeclaringType.FullName == "N.T" && am.Name == "get_StaticProp")
+                {
+                    return FSharpExpr.Lambda(new FSharpVar("", typeof(decimal), null), FSharpExpr.Value<decimal>(4.2M));
+                }
+                else if (am.DeclaringType.FullName == "N.T" && am.Name == "add_Event1")
+                {
+                    // Dummy expr... since we do not care about what it really does...
+                    return FSharpExpr.Lambda(new FSharpVar("", typeof(int), null), FSharpExpr.Value<int>(1));
+                }
+                else if (am.DeclaringType.FullName == "N.T" && am.Name == "remove_Event1")
+                {
+                    // Dummy expr... since we do not care about what it really does...
+                    return FSharpExpr.Lambda(new FSharpVar("", typeof(int), null), FSharpExpr.Value<int>(1));
+                }
+                else
+                {
+                    Debug.Assert(false, "NYI");
+                    throw new NotImplementedException();
+                }
+            }
+            else
+            {
+                Debug.Assert(false, "GetInvokerExpression() invoked with neither ConstructorInfo nor MethodInfo!");
+                return null;
+            }
+            //Expression<Func<S>> e = () => new S(9);
+            //return e.Body;
+
+            //throw new NotImplementedException();
+        }
+
+        public IProvidedNamespace[] GetNamespaces()
+        {
+
+            return new IProvidedNamespace[] { new Namespace1() };
+        }
+
+        public System.Reflection.ParameterInfo[] GetStaticParameters(Type typeWithoutArguments)
+        {
+
+            // No StaticParams
+            return new ParameterInfo[] { /* new myParameterInfo() */ };
+        }
+
+        public event EventHandler Invalidate;
+        public byte[] GetGeneratedAssemblyContents(Assembly assembly) { throw (new Exception("GetGeneratedAssemblyContents - only erased types were provided!!")); }
+    }
+}
diff --git a/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithNullComment/XmlDocAttributeWithNullComment.csproj b/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithNullComment/XmlDocAttributeWithNullComment.csproj
new file mode 100644
index 0000000..84ec886
--- /dev/null
+++ b/vsintegration/src/unittests/Resources.MockTypeProviders/XmlDocAttributeWithNullComment/XmlDocAttributeWithNullComment.csproj
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information. -->
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <FSharpSourcesRoot>..\..\..\..\..\src</FSharpSourcesRoot>
+    <ProjectLanguage>CSharp</ProjectLanguage>
+  </PropertyGroup>
+  <Import Project="$(FSharpSourcesRoot)\FSharpSource.settings.targets" />
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{956BBE41-ABD1-4DBA-9F3B-BA1C9821C98C}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AssemblyName>XmlDocAttributeWithNullComment</AssemblyName>
+    <WarningLevel>4</WarningLevel>
+    <NoWarn>0169;0067</NoWarn>
+    <DefineConstants>DEBUG;TRACE;$(DefineConstants)</DefineConstants>
+    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+    <OutputPath>$(FSharpSourcesRoot)\..\$(Configuration)\$(TargetFramework)\bin\UnitTestsResources\MockTypeProviders</OutputPath>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+    <ProjectReference Include="$(FSharpSourcesRoot)\fsharp\FSharp.Core\FSharp.Core.fsproj">
+      <Project>{DED3BBD7-53F4-428A-8C9F-27968E768605}</Project>
+      <Name>FSharp.Core</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="ArtificalEventInfo.cs" />
+    <Compile Include="ArtificialConstructorInfo.cs" />
+    <Compile Include="ArtificialMethodInfo.cs" />
+    <Compile Include="ArtificialParamInfo.cs" />
+    <Compile Include="ArtificialType.cs" />
+    <Compile Include="ArtificialPropertyInfo.cs" />
+    <Compile Include="TypeProviderInCSharp.cs" />
+    <Compile Include="..\Helpers.cs" />
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+</Project>
diff --git a/vsintegration/src/unittests/Resources/TestTypeProvider.Negative1.fsx b/vsintegration/src/unittests/Resources/TestTypeProvider.Negative1.fsx
new file mode 100644
index 0000000..3d9f0a5
--- /dev/null
+++ b/vsintegration/src/unittests/Resources/TestTypeProvider.Negative1.fsx
@@ -0,0 +1,39 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+namespace HelloWorldTypeProviderNeg1
+
+#r "System.Core.dll"
+#load @"extras\extenders\shared\TypeBuilder.fs"
+
+open System
+open Microsoft.FSharp.Core.CompilerServices
+
+[<TypeProvider>]
+type public HelloWorldProvider() = 
+    let invalidation = new Event<EventHandler,_>()
+
+    interface IProvidedNamespace with
+        member __.NamespaceName = "HelloWorld"
+        member __.GetTypes() = [| |]
+        member __.ResolveTypeName name =  failwith (sprintf "GetType %s" name)
+        member __.GetNestedNamespaces() = [| |]
+    interface IDisposable with
+        member __.Dispose() = ()
+
+    interface ITypeProvider with
+        member this.GetNamespaces() = [| this |] 
+        member __.GetInvokerExpression(syntheticMethodBase, parameterExpressions) = failwith "nyi"
+        member __.ApplyStaticArguments(typeWithoutArguments, typeNameWithArguments, staticArguments) =
+            if staticArguments.Length <> 0 then failwith "this provided type does not accept static parameters" 
+            typeWithoutArguments
+        member __.GetStaticParameters(typeWithoutArguments) = [| |]
+
+        [<CLIEvent>]
+        member x.Invalidate = invalidation.Publish
+        member this.GetGeneratedAssemblyContents(assembly) = failwith "GetGeneratedAssemblyContents - only erased types were provided!!"
+
+
+[<assembly:TypeProviderAssembly("ThisAssemblyDoesNotExist")>]
+do()
+
+
diff --git a/vsintegration/src/unittests/Resources/TestTypeProvider.Positive1.fsx b/vsintegration/src/unittests/Resources/TestTypeProvider.Positive1.fsx
new file mode 100644
index 0000000..f4fe601
--- /dev/null
+++ b/vsintegration/src/unittests/Resources/TestTypeProvider.Positive1.fsx
@@ -0,0 +1,99 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+namespace HelloWorldTypeProvider
+
+#r "System.Core.dll"
+#load @"extras\extenders\shared\TypeBuilder.fs"
+
+open System
+open System.Linq.Expressions
+open System.Reflection
+open Microsoft.FSharp.Core.CompilerServices
+open FSharp.TypeMagic  // utilities for building types
+
+#nowarn "40" // This just suppresses an informational warning that some "recursive knot tying" is used to defined synthetic types and their members. 
+
+module internal SyntheticTypes =
+
+    // This is a non-generative provider - the types are reported as belonging to the provider's assembly
+    let thisAssembly = System.Reflection.Assembly.GetExecutingAssembly()
+
+    // This is the namespace
+    let rootNamespace = "HelloWorld" 
+
+    // This defines all the members in the one synthetic type. A lazy computation is used to ensure the
+    // member array is only created once.
+    let rec allHelloWorldTypeMembers : Lazy<MemberInfo[]> = 
+        lazy 
+            [|  
+                for (propertyName, propertyType) in  [("StaticProperty1", typeof<string>); ("StaticProperty2", typeof<int>) ] do 
+                    let prop = TypeBuilder.CreateSyntheticProperty(helloWorldType,propertyName,propertyType,isStatic=true) 
+                    yield! TypeBuilder.JoinPropertiesIntoMemberInfos [prop]
+            |]  
+
+    // This defines the one synthetic type. Put the type in the namespace, and specify its members.
+    // Because this is a synthetic type it will be erased at runtime. It is erased to 'System.Object'
+    // because that is its first non-synthetic base type.
+    and helloWorldType =
+        let container = TypeContainer.Namespace(thisAssembly.GetModules().[0], rootNamespace)
+        TypeBuilder.CreateSimpleType(container,"HelloWorldType",members=allHelloWorldTypeMembers)
+
+
+ 
+/// The implementation of the compiler extension. The attribute indicates that
+/// is is a non-generative compiler extension.
+[<TypeProvider>]
+type public HelloWorldProvider() = 
+
+    // This event is never triggered in this sample, because the schema never changes
+    let invalidation = new Event<EventHandler,_>()
+
+    // This implements both get_StaticProperty1 and get_StaticProperty2
+    static member GetPropertyByName(propertyName:string) : 'T = 
+        match propertyName with 
+        | "StaticProperty1" -> "You got a static property" |> box |> unbox
+        | "StaticProperty2" -> 42 |> box |> unbox
+        | _ -> failwith "unexpected property"
+
+    interface IProvidedNamespace with
+        member this.GetNestedNamespaces() = [| |]
+        member __.NamespaceName = SyntheticTypes.rootNamespace
+        member __.GetTypes() = [SyntheticTypes.helloWorldType] |> Array.ofList
+        member __.ResolveTypeName name : System.Type = 
+            match name with
+            | "HelloWorldType" -> SyntheticTypes.helloWorldType
+            | _ -> failwith (sprintf "GetType %s" name)
+
+    interface IDisposable with
+        member __.Dispose() = ()
+    interface ITypeProvider with
+        member this.GetNamespaces() = [| this |]
+
+        member this.ApplyStaticArguments(typeWithoutArguments, typeNameWithArguments, staticArguments) =
+            if staticArguments.Length <> 0 then failwith "this provided type does not accept static parameters" 
+            typeWithoutArguments
+
+        member __.GetStaticParameters(typeWithoutArguments) = [| |]
+        member __.GetInvokerExpression(syntheticMethodBase:MethodBase, parameterExpressions:System.Linq.Expressions.ParameterExpression []) = 
+            // trim off the "get_"
+            let propertyName = syntheticMethodBase.Name.Substring(4)
+            if syntheticMethodBase.DeclaringType = SyntheticTypes.helloWorldType then
+                let syntheticMethodBase = syntheticMethodBase :?> MethodInfo
+                let getClassInstancesByName = 
+                    typeof<HelloWorldProvider>
+                        .GetMethod("GetPropertyByName", BindingFlags.Static ||| BindingFlags.Public)
+                        .MakeGenericMethod([|syntheticMethodBase.ReturnType|])
+                upcast Expression.Call(getClassInstancesByName, Expression.Constant(propertyName))
+            else 
+                failwith "unexpected type"
+
+        // This event is never triggered in this sample, because the schema never changes
+        [<CLIEvent>]
+        member x.Invalidate = invalidation.Publish
+
+        member this.GetGeneratedAssemblyContents(assembly) = failwith "GetGeneratedAssemblyContents - only erased types were provided!!"
+
+[<assembly:TypeProviderAssembly>]
+do()
+
+
diff --git a/vsintegration/src/unittests/TestLib.LanguageService.fs b/vsintegration/src/unittests/TestLib.LanguageService.fs
new file mode 100644
index 0000000..56e5ba5
--- /dev/null
+++ b/vsintegration/src/unittests/TestLib.LanguageService.fs
@@ -0,0 +1,476 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+namespace UnitTests.TestLib.LanguageService
+
+open System
+open NUnit.Framework
+open System.Diagnostics
+open System.IO
+open Salsa.Salsa
+open Salsa.VsOpsUtils
+open Salsa.VsMocks
+open UnitTests.TestLib.Salsa
+open UnitTests.TestLib.Utils
+open Microsoft.FSharp.Compiler
+open Internal.Utilities.Debug
+open System.Text.RegularExpressions 
+open Microsoft.FSharp.Compiler.SourceCodeServices
+#nowarn "52" // The value has been copied to ensure the original is not mutated
+
+//open Internal.Utilities
+type internal TextSpan       = Microsoft.VisualStudio.TextManager.Interop.TextSpan
+
+type internal SourceFileKind = FS | FSI | FSX
+
+type internal ISingleFileTestRunner = 
+    abstract CreateSingleFileProject :
+        content : string * 
+        ?references : list<string> * 
+        ?defines : list<string> * 
+        ?fileKind : SourceFileKind *
+        ?disabledWarnings : list<string> * 
+        ?fileName : string -> (OpenSolution * OpenProject * OpenFile)
+    abstract CreateSingleFileProject :
+        content : list<string> * 
+        ?references : list<string> * 
+        ?defines : list<string> * 
+        ?fileKind : SourceFileKind *
+        ?disabledWarnings : list<string>* 
+        ? fileName : string -> (OpenSolution * OpenProject * OpenFile)
+
+type internal Helper =
+    static member TrimOutExtraMscorlibs (libList:list<string>) =
+        // There may be multiple copies of mscorlib referenced; but we're only allowed to use one.  Pick the highest one.
+        let allExceptMscorlib = libList |> List.filter (fun s -> not(s.Contains("mscorlib")))
+        let mscorlibs = libList |> List.filter (fun s -> s.Contains("mscorlib"))
+        // contain e.g. "mscorlib, Version=4.0.0.0 ..."
+        let bestMscorlib = mscorlibs |> List.sort |> List.rev |> List.head
+        bestMscorlib :: allExceptMscorlib
+
+    static member ExhaustivelyScrutinize (sftr : ISingleFileTestRunner, lines:string list) = 
+        let Impl kind = 
+            let (_solution, _project, file) = sftr.CreateSingleFileProject(lines, fileKind = kind)
+            let Check line col = 
+                //printfn "line=%d col=%d" line col
+                MoveCursorTo(file,line,col)
+                let tooltip = GetQuickInfoAtCursor file
+                let parameterInfo = GetParameterInfoAtCursor file
+                let squiggle = GetSquiggleAtCursor file
+                let tokenType = GetTokenTypeAtCursor file
+                let ctrlspacecompletion = CtrlSpaceCompleteAtCursor file
+                if col > 1 && lines.[line-1].[col-2] = '.' then  // -2 because, -1 to get to 0-based coords, and -1 more because want to look one char left of cursor for the dot
+                    let autocompletion = AutoCompleteAtCursor file
+                    ()
+                ()
+            let lines = lines |> List.toArray
+            let lineCount = lines.Length
+            for line in 1..lineCount do 
+                let len = lines.[line-1].Length
+                for col in 1..len do 
+                    Check line col
+        Impl SourceFileKind.FS
+        Impl SourceFileKind.FSX
+
+    static member AssertMemberDataTipContainsInOrder(sftr : ISingleFileTestRunner, code : list<string>,marker,completionName,rhsContainsOrder) =
+        let (_solution, project, file) = sftr.CreateSingleFileProject(code, fileKind = SourceFileKind.FSX)
+        TakeCoffeeBreak(file.VS) (* why needed? *)       
+        MoveCursorToEndOfMarker(file,marker)
+        let completions = AutoCompleteAtCursor file
+        match completions |> Array.tryFind (fun (name, _, _, _) -> name = completionName) with
+        | Some(_, _, descrFunc, _) ->
+            let descr = descrFunc()
+            AssertContainsInOrder(descr,rhsContainsOrder)
+        | None -> 
+            Console.WriteLine("Could not find completion name '{0}'", completionName)
+            for error in (GetErrors(project)) do
+                printf "%s\n" (error.ToString())
+            Assert.Fail()   
+
+    (* Asserts ----------------------------------------------------------------------------- *)
+    static member AssertEqualWithMessage(expected,actual,message) =
+        if expected<>actual then 
+            printf "%s" message
+            Assert.Fail(message)
+    static member AssertEqual(expected,actual) =
+        if expected<>actual then 
+            let message = sprintf "Expected %A but got %A." expected actual
+            printf "%s" message
+            Assert.Fail(message)
+    
+    static member AssertContains(s:string,c) =
+        if not (s.Contains(c)) then
+            printf "Expected '%s' to contain '%s'." s c
+            Assert.Fail()
+    static member AssertArrayContainsPartialMatchOf(a:string array,c) =
+        let found = ref false
+        a |> Array.iter(fun s -> found := s.Contains(c) || !found)
+        if not(!found) then 
+            printfn "Expected: %A" a            
+            printfn "to contain '%s'." c
+            Assert.Fail()            
+    static member AssertNotContains(s:string,c) = 
+        if (s.Contains(c)) then
+            printf "Expected '%s' to not contain '%s'." s c
+            Assert.Fail()   
+
+    static member AssertMatches (r : Regex) (s:string) =
+        if not (r.IsMatch(s)) then
+            printfn "Expected regex '%s' to match '%s'." (r.ToString()) s
+            Assert.Fail()
+
+    static member AssertContainsInOrder(s:string,cs:string list) =
+        let rec containsInOrderFrom fromIndex expects =
+          match expects with
+            | [] -> ()
+            | expect :: expects ->
+                let index = s.IndexOf((expect:string),(fromIndex:int))           
+                if index = -1 then
+                    let s= sprintf "Expected '%s' to contain '%s' after index %d." s expect fromIndex
+                    Console.WriteLine(s)
+                    Assert.Fail(s)
+                else
+                   printfn "At index %d seen '%s'." index expect
+                containsInOrderFrom index expects
+        containsInOrderFrom 0 cs
+
+    static member AssertListContainsInOrder(s:string list,cs:string list) =
+        let s : string array = Array.ofList s
+        let s : string = String.Join("\n",s)
+        AssertContainsInOrder(s,cs)
+
+        // Like AssertMatches, but runs for every prefix of regex up to each occurence of 'c'
+    // Is helpful so that, if long regex match fails, you see first prefix that fails
+    static member AssertMatchesRegex (c : char) (regexStr : string) (s:string) =
+        let mutable i = regexStr.IndexOf(c, 0)
+        while i <> -1 do
+            let r = regexStr.Substring(0,i)
+            let regex = new Regex(r)
+            AssertMatches regex s
+            i <- regexStr.IndexOf(c, i+1)       
+
+type internal GlobalParseAndTypeCheckCounter private(initialParseCount:int, initialTypeCheckCount:int, initialEventNum:int, vs) =
+    static member StartNew(vs) =
+        TakeCoffeeBreak(vs)
+        let n = IncrementalFSharpBuild.GetCurrentIncrementalBuildEventNum()
+        new GlobalParseAndTypeCheckCounter(InteractiveChecker.GlobalForegroundParseCountStatistic, InteractiveChecker.GlobalForegroundTypeCheckCountStatistic, n, vs)
+    member private this.GetEvents() = 
+        TakeCoffeeBreak(vs)
+        let n = IncrementalFSharpBuild.GetCurrentIncrementalBuildEventNum()
+        IncrementalFSharpBuild.GetMostRecentIncrementalBuildEvents(n-initialEventNum)
+    member private this.SawIBDeleted() = 
+        this.GetEvents() |> List.exists (function | IncrementalFSharpBuild.IBEDeleted -> true | _ -> false)
+    member private this.GetParsedFilesSet() = 
+        this.GetEvents() |> List.choose (function | IncrementalFSharpBuild.IBEParsed(file) -> Some(file) | _ -> None) |> set
+    member private this.GetTypeCheckedFilesSet() = 
+        this.GetEvents() |> List.choose (function | IncrementalFSharpBuild.IBETypechecked(file) -> Some(file) | _ -> None) |> set
+    member this.AssertExactly(expectedParses, expectedTypeChecks) =
+        let actualParses = this.GetParsedFilesSet().Count 
+        let actualTypeChecks = this.GetTypeCheckedFilesSet().Count
+        if (actualParses,actualTypeChecks) <> (expectedParses, expectedTypeChecks) then
+            Assert.Fail(sprintf "Expected %d parses and %d typechecks, but got %d parses and %d typechecks." expectedParses expectedTypeChecks actualParses actualTypeChecks)
+    member this.AssertExactly(expectedParses, expectedTypeChecks, expectedParsedFiles : list<OpenFile>, expectedTypeCheckedFiles : list<OpenFile>) =
+        this.AssertExactly(expectedParses, 
+                           expectedTypeChecks, 
+                           expectedParsedFiles |> List.map GetNameOfOpenFile, 
+                           expectedTypeCheckedFiles |> List.map GetNameOfOpenFile,
+                           false)
+    member this.AssertExactly((aap,expectedParsedFiles) : string option * list<OpenFile>, (aat,expectedTypeCheckedFiles) : string option * list<OpenFile>) =
+        this.AssertExactly((aap,expectedParsedFiles), (aat,expectedTypeCheckedFiles), false)
+    member this.AssertExactly((aap,expectedParsedFiles) : string option * list<OpenFile>, (aat,expectedTypeCheckedFiles) : string option * list<OpenFile>, expectDelete : bool) =
+        let p = match aap with 
+                | Some(aap) -> aap :: (expectedParsedFiles |> List.map GetNameOfOpenFile)
+                | _ -> (expectedParsedFiles |> List.map GetNameOfOpenFile)
+        let t = match aat with
+                | Some(aat) -> aat :: (expectedTypeCheckedFiles |> List.map GetNameOfOpenFile)
+                | _ -> (expectedTypeCheckedFiles |> List.map GetNameOfOpenFile)
+        this.AssertExactly(p.Length, t.Length, p, t, expectDelete)
+    member private this.AssertExactly(expectedParses, expectedTypeChecks, expectedParsedFiles : list<string>, expectedTypeCheckedFiles : list<string>, expectDelete : bool) =
+        let note,ok = if expectDelete then
+                        if this.SawIBDeleted() then ("The incremental builder was deleted, as expected",true) else ("The incremental builder was NOT deleted, even though we expected it to be",false)
+                      else
+                        if this.SawIBDeleted() then ("The incremental builder was UNEXPECTEDLY deleted",false) else ("",true)
+        let actualParsedFiles = this.GetParsedFilesSet()
+        let actualTypeCheckedFiles = this.GetTypeCheckedFilesSet()
+        let actualParses = actualParsedFiles.Count 
+        let actualTypeChecks = actualTypeCheckedFiles.Count
+        let expectedParsedFiles = expectedParsedFiles |> set
+        let expectedTypeCheckedFiles = expectedTypeCheckedFiles |> set
+        if (actualParses, actualTypeChecks, actualParsedFiles, actualTypeCheckedFiles) <> (expectedParses, expectedTypeChecks, expectedParsedFiles, expectedTypeCheckedFiles) then
+            let detail = sprintf "ExpectedParse: %A\nActualParse:   %A\n\nExpectedTypeCheck: %A\nActualTypeCheck:   %A\n\n%s"
+                                    expectedParsedFiles actualParsedFiles expectedTypeCheckedFiles actualTypeCheckedFiles note
+            let msg = 
+                if (actualParses, actualTypeChecks) <> (expectedParses, expectedTypeChecks) then
+                    sprintf "Expected %d parses and %d typechecks, but got %d parses and %d typechecks.\n\n%s" expectedParses expectedTypeChecks actualParses actualTypeChecks detail
+                else
+                    sprintf "Expected %d parses and %d typechecks, and got those counts, but unexpected file sets:\n\n%s" expectedParses expectedTypeChecks detail
+            Assert.Fail(msg)
+        elif not ok then
+            Assert.Fail(sprintf "Got expected events, but also: %s" note)
+
+/// REVIEW: Should be able to get data tip when hovering over a class member method name ie  "member private art.attemptUpgradeToMSBuild hierarchy"
+
+(* Not Unittested Yet ----------------------------------------------------------------------------------------------------------------- *)        
+/// FEATURE: Pressing ctrl-j or ctrl-space will bring up the Intellisense completion list at the current cursor.
+/// FEATURE: String literals such as "My dog has fleas" will be colored in in String color.
+/// FEATURE: Source code files with extensions .fs and .ml are recognized by the language service.
+/// FEATURE: Interface files with extensions .fsi and .mli are recognized by the language service.
+/// FEATURE: Double-clicking a word in a comment highlight just the word not the whole comment.
+/// FEATURE: During debugging user may hover over a tooltip and get debugging information about. For example, instance values.
+/// FEATURE: Character literals such as 'x' will be colored in in String color.
+(* ------------------------------------------------------------------------------------------------------------------------------------ *)        
+
+/// FEATURE(nyi): As the user types part of an identifier, for example Console.Wr, he'll get an Intellisense list of members that match.
+/// FEATURE(nyi): The user can press ctrl-i to start an incremental search within the current document.
+/// FEATURE(nyi): Pressing ctrl-} will move cursor to the matching brace. This will work for all brace types.
+/// FEATURE(nyi): If a source file has a #r or #R reference then changes to the referenced assembly will be recognized by the language service.
+/// FEATURE(nyi): If a source file used to have a #r or #R reference and then the user removes it, that assembly will no longer be in scope.
+    
+/// FEATURE(nyi): There is a navigation bar at the top of the text editor window that shows the user all the top-level and second-level constructs in the file.
+/// FEATURE(nyi): Types in the code will be colored with a special BoundType color
+/// FEATURE(nyi): Preprocessor-like keywords aside from #light\#if\#else\#endif will be colored with PreprocessorKeyword color.
+/// FEATURE(nyi): Intellisense for argument names.
+    
+/// PS-FEATURE(nyi): The user may choose to enable mixed-mode debugging by selecting Project Settings\Debug\Enable unamanaged code debugging
+
+/// These are the driver tests. They're parameterized on
+/// various functions that abstract actions over vs.
+type LanguageServiceBaseTests() =  
+
+    let mutable defaultSolution : OpenSolution = Unchecked.defaultof<_>
+    let cache = System.Collections.Generic.Dictionary()
+
+    let mutable defaultVS : VisualStudio = Unchecked.defaultof<_>
+    let mutable currentVS : VisualStudio = Unchecked.defaultof<_>
+    (* VsOps is internal, but this type needs to be public *)
+    let mutable ops : VsOps = fst (Models.MSBuild())
+    let testStopwatch = new Stopwatch()
+
+    (* Timings ----------------------------------------------------------------------------- *)
+    let stopWatch = new Stopwatch()
+    let ResetStopWatch() = stopWatch.Reset(); stopWatch.Start()
+    let time1 op a message = 
+        ResetStopWatch()
+        let result = op a
+        printf "%s %d ms\n" message stopWatch.ElapsedMilliseconds
+        result                         
+               
+    member internal this.VsOpts
+        with set op = ops <- op
+    
+    member internal this.TestRunner : ISingleFileTestRunner = SingleFileTestRunner(this) :> _
+
+    member internal this.VS = currentVS
+
+    member internal this.CreateSingleFileProject
+        (
+            content : string, 
+            ?references : list<string>, 
+            ?defines : list<string>, 
+            ?fileKind : SourceFileKind, 
+            ?disabledWarnings : list<string>,
+            ?fileName : string
+        ) = 
+        let content = content.Split( [|"\r\n"|], StringSplitOptions.None) |> List.ofArray
+        this.CreateSingleFileProject(content, ?references = references, ?defines = defines, ?fileKind = fileKind, ?disabledWarnings = disabledWarnings, ?fileName = fileName)
+
+    member internal this.CreateSingleFileProject
+        (
+            content : list<string>, 
+            ?references : list<string>, 
+            ?defines : list<string>, 
+            ?fileKind : SourceFileKind, 
+            ?disabledWarnings : list<string>,
+            ?fileName : string
+        ) = 
+        assert (box currentVS = box defaultVS)
+        let mkKeyComponent l = 
+            defaultArg l []
+            |> Seq.sort
+            |> String.concat "|"
+        let ext = 
+            match fileKind with
+            | Some SourceFileKind.FS -> ".fs"
+            | Some SourceFileKind.FSI -> ".fsi"
+            | Some SourceFileKind.FSX -> ".fsx"
+            | None -> ".fs"
+        let fileName = (defaultArg fileName "File1") + ext
+
+        let key = 
+            let refs = mkKeyComponent references
+            let defines = mkKeyComponent defines
+            let warnings = mkKeyComponent disabledWarnings
+            (refs, defines, disabledWarnings, fileName.ToLower())
+
+        match cache.TryGetValue key with
+        | true, (proj, file) ->
+            ReplaceFileInMemory file []
+            SaveFileToDisk file
+            TakeCoffeeBreak(currentVS)
+            
+            ReplaceFileInMemory file content
+            SaveFileToDisk file
+            TakeCoffeeBreak(currentVS)
+            defaultSolution, proj, file
+        | false, _ ->
+            let name = string(Guid.NewGuid())
+            let proj = CreateProject(defaultSolution, name)
+
+            for dw in (defaultArg disabledWarnings []) do
+                GlobalFunctions.AddDisabledWarning(proj, dw)
+
+            if defines.IsSome then 
+                GlobalFunctions.SetProjectDefines(proj, defines.Value)
+
+            for r in (defaultArg references []) do 
+                GlobalFunctions.AddAssemblyReference(proj, r)
+
+            let content = String.concat Environment.NewLine content
+            let _ = AddFileFromTextBlob(proj, fileName, content)
+            let file = OpenFile(proj, fileName)
+
+            cache.[key] <- (proj, file)
+
+            TakeCoffeeBreak(currentVS)
+
+            defaultSolution, proj, file
+    
+    member internal this.CreateSolution() = 
+        if (box currentVS = box defaultVS) then
+            failwith "You are trying to modify default instance of VS. The only operation that is permitted on default instance is CreateSingleFileProject, perhaps you forgot to add line 'use _guard = this.WithNewVS()' at the beginning of the test?"
+        GlobalFunctions.CreateSolution(currentVS)
+
+    member internal this.CloseSolution(sln : OpenSolution) = 
+        if (box currentVS = box defaultVS) then
+            failwith "You are trying to modify default instance of VS. The only operation that is permitted on default instance is CreateSingleFileProject, perhaps you forgot to add line 'use _guard = this.WithNewVS()' at the beginning of the test?"
+        if (box sln.VS <> box currentVS) then
+            failwith "You are trying to close solution that is not belongs to the active instance VS. This may denote the presence of errors in tests."
+
+        GlobalFunctions.CloseSolution(sln)
+
+    member internal this.AddAssemblyReference(proj, ref) = 
+        if (box currentVS = box defaultVS) then
+            failwith "You are trying to modify default instance of VS. The only operation that is permitted on default instance is CreateSingleFileProject, perhaps you forgot to add line 'use _guard = this.WithNewVS()' at the beginning of the test?"
+
+        GlobalFunctions.AddAssemblyReference(proj, ref)
+
+    /// Called per test run
+    [<TestFixtureSetUp>]
+    member this.TestFixtureSetUp() =
+        ApproveAllMockTypeProviders()
+        match Internal.Utilities.FSharpEnvironment.BinFolderOfDefaultFSharpCompiler with 
+        | Some(folder) -> 
+            let fscPath = Path.Combine(folder,"fsc.exe")
+            System.Diagnostics.Debug.Assert(File.Exists(fscPath), sprintf "Path to fsc.exe (%s) does not exist. Unittests will surely fail. Is Unittest.exe.config stale?" fscPath)
+        | None -> 
+            System.Diagnostics.Debug.Assert(false, "No path to fsc.exe found. Unittests will surely fail.")
+
+        let AssertNotAssemblyNameContains(a:System.Reflection.Assembly, text1:string, text2:string) = 
+            let fullname = sprintf "%A" a
+            if fullname.Contains(text1) && fullname.Contains(text2) then
+                // Can't throw an exception here because its in an event handler.
+                System.Diagnostics.Debug.Assert(false, sprintf "Unexpected: loaded assembly '%s' to not contain '%s' and '%s'" fullname text1 text2)
+
+        // Under .NET 4.0 we don't allow 3.5.0.0 assemblies
+        let AssertNotBackVersionAssembly(args:AssemblyLoadEventArgs) =
+            Trace.PrintLine("AssembliesLoadedByUnittests",fun _ -> sprintf "ASSEMBLY LOAD: %A" (args.LoadedAssembly))
+
+            // We're worried about loading these when running against .NET 4.0:
+            // Microsoft.Build.Tasks.v3.5, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+            // Microsoft.Build.Utilities.v3.5, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+            AssertNotAssemblyNameContains(args.LoadedAssembly,"Microsoft.Build", "Version=3.5.0.0") 
+            ()
+        AppDomain.CurrentDomain.AssemblyLoad.Add AssertNotBackVersionAssembly
+
+        UIStuff.SetupSynchronizationContext()
+        new Microsoft.VisualStudio.FSharp.LanguageService.FSharpPackage() |> ignore  // will force us to capture the dummy context we just set up
+            
+        defaultVS <- ops.CreateVisualStudio()
+        currentVS <- defaultVS
+        
+        defaultSolution <- GlobalFunctions.CreateSolution(defaultVS)
+        cache.Clear()
+
+    [<TestFixtureTearDown>]
+    member this.Shutdown() =
+        if box currentVS <> box defaultVS then
+            failwith "LanguageServiceBaseTests.Shutdown was called when 'active' instance of VS is not 'default' one - this may denote that tests contains errors"
+        
+        GlobalFunctions.Cleanup(defaultVS)
+        cache.Clear()
+
+    member this.UsingNewVS() = 
+        if box currentVS <> box defaultVS then
+            failwith "LanguageServiceBaseTests.UsingNewVS was called when 'active' instance of VS is not 'default' one - this may denote that tests contains errors"
+        currentVS <- ops.CreateVisualStudio()
+        { new System.IDisposable with 
+            member __.Dispose() = 
+                if box currentVS = box defaultVS then
+                    failwith "At this moment 'current' instance of VS cannot be the same as the 'default' one. This may denote that tests contains errors."
+                GlobalFunctions.Cleanup(currentVS)
+                currentVS <- defaultVS }
+
+
+    /// Called per test
+    [<SetUp>]
+    member this.Setup() =
+        if box currentVS <> box defaultVS then
+            failwith "LanguageServiceBaseTests.Setup was called when 'active' instance of VS is not 'default' one - this may denote that tests contains errors"
+        
+        // reset state of default VS instance that can be shared among the tests
+        ShiftKeyUp(currentVS)
+        ops.CleanInvisibleProject(currentVS)
+
+//        do setDiagnosticsChannel(Some(Console.Out));
+        do AbstractIL.Diagnostics.setDiagnosticsChannel(None);
+        // To disable a logging class, put an underscore _after_ its name.
+        //Trace.Log <- "ChangeEvents_;SyncOp_;Reactor_;ProjectSite_;IncrementalBuild_;Build_;Salsa_;SalsaUndo_;MSBuild_;MSBuildPerf_;IncrementalBuildWorkUnits_;LanguageService_;StripSystemImportsFromTcConfig_;ProjectSystem_"
+//        Trace.Log <- "*"
+        ResetStopWatch()
+        testStopwatch.Reset()
+        testStopwatch.Start()
+        ()
+        
+    /// Called per test
+    [<TearDown>]
+    member this.TearDown() =
+
+
+#if DEBUG_FIND_SLOWEST_TESTS
+        if testStopwatch.ElapsedMilliseconds > 15000L then
+            let msg = sprintf "a test took %dms" testStopwatch.ElapsedMilliseconds
+            stderr.WriteLine(msg)
+            System.Console.Beep()
+            System.Windows.MessageBox.Show(msg) |> ignore
+#endif
+        // help find leaks per-test
+//        System.GC.Collect()  
+//        System.GC.WaitForPendingFinalizers()
+#if DEBUG
+        if Microsoft.VisualStudio.FSharp.LanguageService.TaskReporter.AliveCount <> 0 then
+            Debug.Assert(false, sprintf "There are %d TaskReporters still alive" Microsoft.VisualStudio.FSharp.LanguageService.TaskReporter.AliveCount)
+#endif
+        ()
+
+and internal SingleFileTestRunner(owner : LanguageServiceBaseTests) =
+    interface ISingleFileTestRunner with
+        member sftr.CreateSingleFileProject
+            (
+                content : string, 
+                ?references : list<string>, 
+                ?defines : list<string>, 
+                ?fileKind : SourceFileKind, 
+                ?disabledWarnings : list<string>,
+                ?fileName : string
+            ) = 
+            owner.CreateSingleFileProject(content, ?references = references, ?defines = defines, ?fileKind = fileKind, ?disabledWarnings = disabledWarnings, ?fileName = fileName)
+
+        member sftr.CreateSingleFileProject
+            (
+                content : list<string>, 
+                ?references : list<string>, 
+                ?defines : list<string>, 
+                ?fileKind : SourceFileKind, 
+                ?disabledWarnings : list<string>,
+                ?fileName : string
+            ) = 
+            owner.CreateSingleFileProject(content, ?references = references, ?defines = defines, ?fileKind = fileKind, ?disabledWarnings = disabledWarnings, ?fileName = fileName)
diff --git a/vsintegration/src/unittests/TestLib.ProjectSystem.fs b/vsintegration/src/unittests/TestLib.ProjectSystem.fs
new file mode 100644
index 0000000..1a6acd0
--- /dev/null
+++ b/vsintegration/src/unittests/TestLib.ProjectSystem.fs
@@ -0,0 +1,720 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+namespace UnitTests.TestLib.ProjectSystem
+
+open System 
+open System.CodeDom
+open System.CodeDom.Compiler
+open System.Runtime.Serialization
+open System.Collections.Generic
+open System.Text.RegularExpressions
+open System.Diagnostics
+open Internal.Utilities.Debug
+open System.IO
+open System.Text
+open System.Xml.Linq
+open Salsa
+
+open Microsoft.Win32
+
+open Microsoft.VisualStudio.FSharp.ProjectSystem
+open Microsoft.VisualStudio.Shell.Interop
+
+open Microsoft.Build.BuildEngine
+open Microsoft.Build.Execution
+open Microsoft.Build.Framework
+        
+#nowarn "52" // The value has been copied to ensure the original is not mutated
+open NUnit.Framework
+
+open UnitTests.TestLib.Utils
+open UnitTests.TestLib.Utils.Asserts
+open UnitTests.TestLib.Utils.FilesystemHelpers
+
+type internal UnitTestingFSharpProjectNode(package:FSharpProjectPackage) as this =
+    inherit FSharpProjectNode(package) 
+
+    do this.InteropSafeIVsHierarchy <- this
+       this.InteropSafeIVsUIHierarchy <- this
+       this.InteropSafeIVsProject <- this
+       this.InteropSafeIVsSccProject2 <- this
+       this.InteropSafeIVsProjectFlavorCfgProvider <- this
+
+type AddReferenceDialogTab =
+    | DotNetTab = 0
+    | BrowseTab = 1
+
+// helper type for representing solution-explorer tree
+[<StructuralEquality; NoComparison>]
+type Tree<'T> =
+    | Tree of (*data*)'T * (*firstChild*)Tree<'T> * (*nextSibling*)Tree<'T>
+    | Nil
+
+type TheTests() = 
+    static let Net35RefAssemPathOnThisMachine() =
+        let key = @"SOFTWARE\Microsoft\.NETFramework\AssemblyFolders\Microsoft .NET Framework 3.5 Reference Assemblies"
+        let hklm = Registry.LocalMachine
+        let rkey = hklm.OpenSubKey(key)
+        rkey.GetValue("") :?> string
+
+    static let ANYTREE = Tree("",Nil,Nil)
+   
+            
+    /////////////////////////////////
+    // project helpers
+    static let SaveProject(project : UnitTestingFSharpProjectNode) =
+        project.Save(null, 1, 0u) |> ignore
+
+    static let DefaultBuildActionOfFilename(filename) : Salsa.BuildAction = 
+        match Path.GetExtension(filename) with 
+        | ".fsx" -> Salsa.BuildAction.None
+        | ".resx"
+        | ".resources" -> Salsa.BuildAction.EmbeddedResource
+        | _ -> Salsa.BuildAction.Compile            
+
+    static let GetReferenceContainerNode(project : ProjectNode) =
+        let l = new List<ReferenceContainerNode>()
+        project.FindNodesOfType(l)
+        l.[0]            
+        
+    /////////////////////////////////
+    /// Called per test
+    [<SetUp>]
+    member this.Setup() =
+        ()
+
+        
+    [<TearDown>]
+    member this.TearDown() =
+        // help find leaks per-test
+        System.GC.Collect()  
+        System.GC.WaitForPendingFinalizers()
+#if DEBUG
+        printfn "TearDown..."
+        if Microsoft.VisualStudio.FSharp.LanguageService.TaskReporter.AliveCount <> 0 then
+            Debug.Assert(false, sprintf "There are %d TaskReporters still alive" Microsoft.VisualStudio.FSharp.LanguageService.TaskReporter.AliveCount)
+#endif
+        ()
+
+    /////////////////////////////////
+    /// helpers
+    static member AssertMatches (r : Regex) (s:string) =
+        if not (r.IsMatch(s)) then
+            let msg = sprintf "Expected regex '%s' to match '%s'." (r.ToString()) s
+            printfn "%s" msg
+            Assert.Fail(msg)
+    // Like AssertMatches, but runs for every prefix of regex up to each occurence of 'c'
+    // Is helpful so that, if long regex match fails, you see first prefix that fails
+    static member HelpfulAssertMatches (c : char) (regexStr : string) (s:string) =
+        let mutable i = regexStr.IndexOf(c, 0)
+        while i <> -1 do
+            let r = regexStr.Substring(0,i)
+            let regex = new Regex(r)
+            TheTests.AssertMatches regex s
+            i <- regexStr.IndexOf(c, i+1)
+        TheTests.AssertMatches (new Regex(regexStr)) s
+
+    static member PrintHierarchy(node : HierarchyNode) =
+        let rec nSpaces n = 
+            if n = 0 then "" else "    " + nSpaces (n-1)
+        let rec Print(node : HierarchyNode, level : int) =
+            printfn "%s%s" (nSpaces level) node.Caption
+            if node.FirstChild <> null then
+                Print(node.FirstChild, level + 1)
+            if node.NextSibling <> null then
+                Print(node.NextSibling, level)
+        Print(node, 0)
+
+    static member internal CreateProject(filename : string, forceUTF8 : string, configChangeNotifier, serviceProvider) =
+        UIStuff.SetupSynchronizationContext()
+        let buildEngine = Utilities.InitializeMsBuildEngine(null)
+        let buildProject = Utilities.InitializeMsBuildProject(buildEngine, filename)
+        let package = new FSharpProjectPackage()
+        let project = new UnitTestingFSharpProjectNode(package)
+        try
+            project.SetSite(serviceProvider) |> ignore
+            project.BuildProject <- buildProject
+            let _ = project.BaseURI // This property needs to be touched at least once while the .BuildProject is populated
+            let mutable cancelled = 0
+            let mutable guid = Guid.NewGuid()
+            printfn "about to load .fsproj"
+            project.Load(filename, null, null, 2u, &guid, &cancelled)
+            printfn "loaded"
+            let slfpe = new SolutionListenerForProjectEvents(project.Site)
+            project.ProjectEventsProvider <- (slfpe :> IProjectEvents)
+            slfpe.OnAfterOpenProject((project :> IVsHierarchy), 0) |> ignore
+            MSBuildProject.SetGlobalProperty(project.BuildProject, "UTF8Output", forceUTF8)
+            project
+        with 
+        | e -> project.Close() |> ignore
+               reraise()
+
+    static member internal CreateProject(filename : string) =
+        let sp, configChangeNotifier = VsMocks.MakeMockServiceProviderAndConfigChangeNotifier()
+        let p = TheTests.CreateProject(filename, "false", configChangeNotifier, sp)
+        // ensure that vs-style encoding is off
+        p
+        
+    static member internal CreateProjectWithUTF8Output(filename : string) =
+        let sp, configChangeNotifier = VsMocks.MakeMockServiceProviderAndConfigChangeNotifier()
+        let p = TheTests.CreateProject(filename, "true", configChangeNotifier, sp)
+        p
+      
+    static member internal FindNodeWithCaption(project : UnitTestingFSharpProjectNode, caption) =
+        let node = project.FirstChild
+        let rec TryFind (n : HierarchyNode) =
+            if n = null then None 
+            elif n.Caption = caption then Some(n) 
+            else match TryFind(n.FirstChild) with
+                 | None -> TryFind(n.NextSibling)
+                 | x -> x
+        match TryFind node with
+        | Some(x) -> x
+        | None -> failwith "did not find node with caption %s" caption
+       
+    static member MoveDown(node : HierarchyNode) =
+        match node with
+        | :? FSharpFileNode 
+        | :? FSharpFolderNode -> 
+            TheTests.EnsureMoveDownEnabled(node)
+            node.ExecCommandOnNode(VSProjectConstants.guidFSharpProjectCmdSet, 
+                                   uint32 VSProjectConstants.MoveDownCmd.ID,
+                                   uint32 0, new IntPtr(0), new IntPtr(0)) |> ignore
+        | _ -> failwith "unexpected node type"
+        ()
+
+    static member MoveUp(node : HierarchyNode) =
+        match node with
+        | :? FSharpFileNode 
+        | :? FSharpFolderNode ->
+            TheTests.EnsureMoveUpEnabled(node)
+            node.ExecCommandOnNode(VSProjectConstants.guidFSharpProjectCmdSet, 
+                                   uint32 VSProjectConstants.MoveUpCmd.ID,
+                                   uint32 0, new IntPtr(0), new IntPtr(0)) |> ignore
+        | _ -> failwith "unexpected node type"
+        ()
+
+    static member EnsureMoveDownDisabled(node : HierarchyNode) =
+        // Move Down appears on menu, but is greyed out
+        let mutable qsr = new QueryStatusResult()
+        ValidateOK(node.QueryStatusOnNode(VSProjectConstants.guidFSharpProjectCmdSet, uint32 VSProjectConstants.MoveDownCmd.ID, 0n, &qsr))
+        let expected = QueryStatusResult.SUPPORTED
+        AssertEqual expected qsr
+        
+    static member EnsureMoveDownEnabled(node : HierarchyNode) =
+        // Move Down appears on menu, and can be clicked
+        let mutable qsr = new QueryStatusResult()
+        ValidateOK(node.QueryStatusOnNode(VSProjectConstants.guidFSharpProjectCmdSet, uint32 VSProjectConstants.MoveDownCmd.ID, 0n, &qsr))
+        let expected = QueryStatusResult.SUPPORTED ||| QueryStatusResult.ENABLED
+        AssertEqual expected qsr
+             
+    static member EnsureMoveUpDisabled(node : HierarchyNode) =
+        // Move Up appears on menu, but is greyed out
+        let mutable qsr = new QueryStatusResult()
+        ValidateOK(node.QueryStatusOnNode(VSProjectConstants.guidFSharpProjectCmdSet, uint32 VSProjectConstants.MoveUpCmd.ID, 0n, &qsr))
+        let expected = QueryStatusResult.SUPPORTED
+        AssertEqual expected qsr
+        
+    static member EnsureMoveUpEnabled(node : HierarchyNode) =
+        // Move Up appears on menu, and can be clicked
+        let mutable qsr = new QueryStatusResult()
+        ValidateOK(node.QueryStatusOnNode(VSProjectConstants.guidFSharpProjectCmdSet, uint32 VSProjectConstants.MoveUpCmd.ID, 0n, &qsr))
+        let expected = QueryStatusResult.SUPPORTED ||| QueryStatusResult.ENABLED
+        AssertEqual expected qsr
+             
+    static member SimpleFsprojText(compileItems : string list, references : string list, other : string) = 
+        TheTests.FsprojTextWithProjectReferences(compileItems, references, [], other)
+        
+    static member SimpleFsprojTextOtherFlags(compileItems : string list, references : string list, otherflags : string, other : string) = 
+        TheTests.FsprojTextWithProjectReferencesAndOtherFlags(compileItems, references, [], otherflags, other)
+    
+    static member public FsprojTextWithProjectReferences(compileItems : string list, references : string list, projectReferences : string list, other : string) = 
+        let vsops = fst (Salsa.Salsa.Models.MSBuild())
+        let references = references |> List.map (fun r->r,false)
+        let text = vsops.CreatePhysicalProjectFileInMemory [for i in compileItems -> (i,DefaultBuildActionOfFilename i, None)] references projectReferences [] [] null null other null
+        printfn "%s" text
+        text
+        
+    static member public FsprojTextWithProjectReferencesAndOtherFlags(compileItems : string list, references : string list, projectReferences : string list, otherflags : string, other : string, targetFramework : string) = 
+        let vsops = fst (Salsa.Salsa.Models.MSBuild())
+        let references = references |> List.map (fun r->r,false)
+        let text = vsops.CreatePhysicalProjectFileInMemory [for i in compileItems -> (i,DefaultBuildActionOfFilename i, None)] references projectReferences [] [] null otherflags other targetFramework
+        printfn "%s" text
+        text
+
+    static member public FsprojTextWithProjectReferencesAndOtherFlags(compileItems : string list, references : string list, projectReferences : string list, otherflags : string, other : string) = 
+        TheTests.FsprojTextWithProjectReferencesAndOtherFlags(compileItems, references, projectReferences, otherflags, other, null)
+
+    static member AssertSameTree(expectation : Tree<string>, node : HierarchyNode) =
+        printfn "actual hierarchy in solution explorer:"
+        TheTests.PrintHierarchy(node)
+        TheTests.AssertSameTreeHelper(expectation, node)
+
+    static member AssertSameTreeHelper(expectation : Tree<string>, node : HierarchyNode) =
+        match expectation with
+        | Tree _ as x when Object.Equals(x, ANYTREE) -> ()
+        | Nil -> 
+            AssertEqual null node
+        | Tree(name,firstChild,nextSibling) -> 
+            AssertEqual name node.Caption
+            TheTests.AssertSameTreeHelper(firstChild, node.FirstChild)
+            TheTests.AssertSameTreeHelper(nextSibling, node.NextSibling)
+        ()
+
+    static member AssertSimilarXml(expectation : XElement, actual : XElement) =
+        // compares element/attribute structure, LocalName, and Value, but ignores Namespace
+        // can expect attribute value "ANY", which matches anything
+        let rec Match(expectation : XElement, actual : XElement, outerContext : string) =
+            let TryLookup(d : IDictionary<_,_>, key : 'k) =
+                let mutable value = Unchecked.defaultof<'v>
+                if d.TryGetValue(key, &value) then
+                    Some value
+                else
+                    None
+            let initialContext = 
+                sprintf "%sWhile expecting '\n%s\n' to match '\n%s\n', " 
+                    outerContext 
+                    (expectation.ToString(SaveOptions.None)) 
+                    (actual.ToString(SaveOptions.None))
+            let Err s = 
+                sprintf "%sfound error:\n%s" initialContext s
+            if expectation.Name.LocalName <> actual.Name.LocalName then
+                Assert.Fail(Err <| sprintf "Expected element name '%s' but got '%s'" expectation.Name.LocalName actual.Name.LocalName)
+            let exAttrs = expectation.Attributes() |> Seq.map (fun a -> a.Name.LocalName, a.Value) |> dict
+            let actAttrs = actual.Attributes() |> Seq.map (fun a -> a.Name.LocalName, a.Value) |> dict
+            if exAttrs.Count <> actAttrs.Count then
+                Assert.Fail(Err <| sprintf "Expected '%d' attributes, but found '%d'" exAttrs.Count actAttrs.Count)
+            for kvp in exAttrs do
+                match TryLookup(actAttrs, kvp.Key) with
+                | None -> Assert.Fail(Err <| sprintf "Expected attribute with localname '%s', but none present" kvp.Key)
+                | Some(v) -> if kvp.Value <> "ANY" && kvp.Value <> v then
+                                 Assert.Fail(Err <| sprintf "Expected attribute '%s' to have value '%s', but actually had '%s'" kvp.Key kvp.Value v)
+            let exLen = Seq.length (expectation.Elements())
+            let actLen = Seq.length (actual.Elements())
+            if exLen <> actLen then
+                Assert.Fail(Err <| sprintf "Expected '%d' sub-elements, but found '%d'" exLen actLen)
+            (expectation.Elements(), actual.Elements()) ||> Seq.iter2 (fun x y -> Match(x,y,initialContext+"\n"))
+        Match(expectation, actual, "")
+    
+    static member internal GetCompileItems (project : UnitTestingFSharpProjectNode) =
+        let MakeRelativePath (file : string) =
+            let projDir = project.ProjectFolder + "\\"
+            if file.StartsWith(projDir) then 
+                file.Substring(projDir.Length)
+            else
+                file
+        project.GetCompileItems() |> Array.toList |> List.map MakeRelativePath
+ 
+    member internal this.MakeProjectAndDoWithProjectFileAndConfigChangeNotifierDispose(dispose : bool, compileItems : string list, references : string list, other : string, targetFramework : string, f : UnitTestingFSharpProjectNode -> _ -> string -> unit) =
+        UIStuff.SetupSynchronizationContext()
+
+        DoWithTempFile "Test.fsproj" (fun file ->
+            File.AppendAllText(file, TheTests.FsprojTextWithProjectReferencesAndOtherFlags(compileItems, references, [], null, other, targetFramework))
+            let sp, cnn = 
+                match targetFramework with
+                | "v4.5" -> VsMocks.MakeMockServiceProviderAndConfigChangeNotifier45()
+                | "v4.0" -> VsMocks.MakeMockServiceProviderAndConfigChangeNotifier40()
+                | "v3.5" -> VsMocks.MakeMockServiceProviderAndConfigChangeNotifier35()
+                | "v3.0" -> VsMocks.MakeMockServiceProviderAndConfigChangeNotifier30()
+                | "v2.0" -> VsMocks.MakeMockServiceProviderAndConfigChangeNotifier20()
+                | null -> VsMocks.MakeMockServiceProviderAndConfigChangeNotifier40()
+                | _ -> failwithf "unexpected targetFramework %s" targetFramework
+            let project = TheTests.CreateProject(file, "false", cnn, sp)
+            try
+                f project cnn file
+            finally
+                if dispose then project.Close() |> ignore
+        )
+
+    member internal this.MakeProjectAndDoWithProjectFileAndConfigChangeNotifierDispose(dispose : bool, compileItems : string list, references : string list, other : string, f : UnitTestingFSharpProjectNode -> _ -> string -> unit) =
+        this.MakeProjectAndDoWithProjectFileAndConfigChangeNotifierDispose(dispose, compileItems, references, other, null, f)
+
+    member internal this.MakeProjectAndDoWithProjectFileAndConfigChangeNotifier(compileItems : string list, references : string list, other : string, targetFramework : string, f : UnitTestingFSharpProjectNode -> _ -> string -> unit) =
+        this.MakeProjectAndDoWithProjectFileAndConfigChangeNotifierDispose(true, compileItems, references, other, targetFramework, f)
+
+    member internal this.MakeProjectAndDoWithProjectFileAndConfigChangeNotifier(compileItems : string list, references : string list, other : string, f : UnitTestingFSharpProjectNode -> _ -> string -> unit) =
+        this.MakeProjectAndDoWithProjectFileAndConfigChangeNotifier(compileItems, references, other, null, f)
+        
+    member internal this.MakeProjectAndDoWithProjectFile(compileItems : string list, references: string list, other : string, targetFramework : string, f : UnitTestingFSharpProjectNode -> string -> unit) =
+        this.MakeProjectAndDoWithProjectFileAndConfigChangeNotifier(compileItems, references, other, targetFramework, fun proj _ s -> f proj s)
+    
+    member internal this.MakeProjectAndDoWithProjectFile(compileItems : string list, references: string list, other : string, f : UnitTestingFSharpProjectNode -> string -> unit) =
+        this.MakeProjectAndDoWithProjectFile(compileItems, references, other, null, f)
+
+    /// Create a project with the given "compileItems" and "other", then 
+    /// call "f" on that project while the project file still exists on disk.
+    member internal this.MakeProjectAndDo(compileItems : string list, references : string list, other : string, f : UnitTestingFSharpProjectNode -> unit) =
+        this.MakeProjectAndDo(compileItems, references, other, null, f)
+
+    member internal this.MakeProjectAndDo(compileItems : string list, references : string list, other : string, targetFramework : string, f : UnitTestingFSharpProjectNode -> unit) =
+        this.MakeProjectAndDoWithProjectFile(compileItems, references, other, targetFramework, fun proj _ -> f proj)
+
+    /// Create a project with the given "compileItems" and "other".
+    member internal this.MakeProject(compileItems : string list, references : string list, other : string) =
+        let project = ref (Unchecked.defaultof<UnitTestingFSharpProjectNode>)
+        this.MakeProjectAndDoWithProjectFileAndConfigChangeNotifierDispose(false, compileItems, references, other, (fun p _ _ ->
+            project := p
+        ))
+        !project
+
+    
+    member this.``FsprojFileToSolutionExplorer.PositiveTest``(compileItems : string list, other : string, expectations : Tree<string>) =
+        use project = this.MakeProject(compileItems, [], other) :> HierarchyNode
+        let node = project.FirstChild
+        TheTests.AssertSameTree(expectations, node)
+        () 
+
+    member internal this.EnsureCausesNotification(project, code) =
+        let ipsf = project :> Microsoft.VisualStudio.FSharp.LanguageService.IProvideProjectSite
+        let ips = ipsf.GetProjectSite()
+        let changed = ref false
+        let handle = ips.AdviseProjectSiteChanges("EnsureCausesNotificationTest", new Microsoft.VisualStudio.FSharp.LanguageService.AdviseProjectSiteChanges(fun () -> changed := true))
+        code()
+        AssertEqual true (!changed)
+    static member MsBuildCompileItems(project : Microsoft.Build.Evaluation.Project) =
+        [for bi in project.Items do
+            if bi.ItemType = "Compile" then
+                yield bi.EvaluatedInclude] 
+    member this.MSBuildProjectBoilerplate (outputType : string) : string =
+        let template = @"
+  <PropertyGroup>
+    <Configuration Condition="" '$(Configuration)' == '' "">Debug</Configuration>
+    <Platform Condition="" '$(Platform)' == '' "">AnyCPU</Platform>
+    <OutputType>{0}</OutputType>
+    <RootNamespace>Blah</RootNamespace>
+    <AssemblyName>Blah</AssemblyName>
+    <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+    <Name>Blah</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>           
+           "
+        String.Format(template, outputType)
+        
+    member this.MSBuildProjectMulitplatBoilerplate (outputType : string) : string =
+        let template = @"
+  <PropertyGroup>
+    <Configuration Condition="" '$(Configuration)' == '' "">Debug</Configuration>
+    <Platform Condition="" '$(Platform)' == '' "">AnyCPU</Platform>
+    <OutputType>{0}</OutputType>
+    <RootNamespace>Blah</RootNamespace>
+    <AssemblyName>Blah</AssemblyName>
+    <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+    <Name>Blah</Name>
+  </PropertyGroup>
+  <PropertyGroup Condition="" '$(Configuration)|$(Platform)' == 'Debug|x86' "">
+    <PlatformTarget>x86</PlatformTarget>
+    <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)' == '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>           
+           "
+        String.Format(template, outputType)
+        
+    member this.MSBuildProjectMultiConfigBoilerplate  (configs : (string*string) list): string =
+        let template = @"
+              <PropertyGroup>
+                <Configuration Condition="" '$(Configuration)' == '' "">Debug</Configuration>
+                <Platform Condition="" '$(Platform)' == '' "">AnyCPU</Platform>
+                <OutputType>Library</OutputType>
+                <RootNamespace>Blah</RootNamespace>
+                <AssemblyName>Blah</AssemblyName>
+                <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
+                <FileAlignment>512</FileAlignment>
+                <Name>Blah</Name>
+              </PropertyGroup>"
+        let sb = new StringBuilder(template)     
+        for (configName,customStr) in configs do
+            let platTemplate =
+                @"<PropertyGroup Condition="" '$(Configuration)|$(Platform)' == '{0}|x86' "">
+                    <PlatformTarget>x86</PlatformTarget>
+                    {1}
+                    <OutputPath>bin\{0}\</OutputPath>
+                  </PropertyGroup>             
+                  <PropertyGroup Condition="" '$(Configuration)|$(Platform)' == '{0}|AnyCPU' "">
+                    <PlatformTarget>AnyCPU</PlatformTarget>                  
+                    {1}
+                    <OutputPath>bin\{0}\</OutputPath>                  
+                  </PropertyGroup>"           
+            String.Format(platTemplate, configName, customStr) |> sb.Append |> ignore
+        sb.ToString()
+        
+    member this.MSBuildProjectMultiPlatform  (platforms : (string*string) list,?defaultPlatform): string =
+        let platform = defaultArg defaultPlatform "AnyCPU"
+        let template = @"
+              <PropertyGroup>
+                <Configuration Condition="" '$(Configuration)' == '' "">Debug</Configuration>
+                <Platform Condition="" '$(Platform)' == '' "">{0}</Platform>
+                <OutputType>Library</OutputType>
+                <RootNamespace>Blah</RootNamespace>
+                <AssemblyName>Blah</AssemblyName>
+                <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
+                <FileAlignment>512</FileAlignment>
+                <Name>Blah</Name>
+              </PropertyGroup>"
+        let sb = new StringBuilder(String.Format(template,platform))     
+        for (platformName,customStr) in platforms do
+            let platTemplate =
+                @"<PropertyGroup Condition="" '$(Configuration)|$(Platform)' == 'Release|{0}' "">
+                    <OutputPath>bin\Release\</OutputPath>                    
+                    {1}
+                    <PlatformTarget>{0}</PlatformTarget>
+                  </PropertyGroup>             
+                  <PropertyGroup Condition="" '$(Configuration)|$(Platform)' == 'Debug|{0}' "">
+                    <OutputPath>bin\Debug\</OutputPath>                    
+                    {1}                                      
+                    <PlatformTarget>{0}</PlatformTarget>                  
+                  </PropertyGroup>"           
+            String.Format(platTemplate, platformName, customStr) |> sb.Append |> ignore
+        sb.ToString()
+    member internal this.CheckConfigNames (project:UnitTestingFSharpProjectNode, expectedNames : string[])=
+        let cfgNames = Array.create expectedNames.Length ""
+        let actual = [| 0u |]
+        project.ConfigProvider.GetCfgNames(uint32 cfgNames.Length, cfgNames, actual) |> AssertEqual VSConstants.S_OK
+        AssertEqualMsg expectedNames cfgNames "List of config names is different"
+        AssertEqualMsg expectedNames.Length (int actual.[0]) "List of config names is ok, but reported lengths disagree"
+                
+    member internal this.CheckPlatformNames(project:UnitTestingFSharpProjectNode, expectedNames : string[])=
+        let platformNames = Array.create expectedNames.Length ""
+        let actual = [| 0u |]
+        project.ConfigProvider.GetPlatformNames(uint32 platformNames.Length, platformNames, actual) |> AssertEqual VSConstants.S_OK
+        AssertEqualMsg expectedNames platformNames "List of platform names is different"
+        AssertEqualMsg expectedNames.Length (int actual.[0]) "List of platfrom names is ok, but reported lengths disagree"
+
+
+    member internal this.HelperEnsureAtLeastOne projFileBoilerplate expectedConfigs expectedPlatforms =
+        this.MakeProjectAndDoWithProjectFile(["foo.fs"], [], projFileBoilerplate,
+            (fun project projFileName ->
+                this.CheckPlatformNames(project, expectedPlatforms)
+                this.CheckConfigNames(project, expectedConfigs)
+            ))
+ 
+
+and (*type*) MSBuildItem =
+    | FolderItem of string      // Include="relativeDir"
+    | CompileItem of string     // Include="relDir\filename.fs"
+    | LinkedCompileItem of (*include:*)string * (*link:*)string   // Include="relDir\filename" Link:nameInSolnExplorer
+    | OtherItem of (*name:*)string * (*include:*)string           // <name Include="include"/>
+    override this.ToString() =
+        match this with
+        | FolderItem(s) -> sprintf @"<Folder Include=""%s"" />" s
+        | CompileItem(s) -> sprintf @"<Compile Include=""%s"" />" s
+        | LinkedCompileItem(inc,n) -> sprintf @"<Compile Include=""%s""><Link>%s</Link></Compile>" inc n
+        | OtherItem(name,inc) -> sprintf @"<%s Include=""%s"" />" name inc
+    member this.AsRegexString() =
+        match this with
+        | FolderItem(s) -> sprintf @"\s*<Folder Include=""%s"" />\s*" (Regex.Escape s)
+        | CompileItem(s) -> sprintf @"\s*<Compile Include=""%s"" />\s*" (Regex.Escape s)
+        | LinkedCompileItem(inc,n) -> sprintf @"\s*<Compile Include=""%s"">\s*<Link>%s</Link>\s*</Compile>\s*" (Regex.Escape inc) (Regex.Escape n)
+        | OtherItem(name,inc) -> sprintf @"\s*<%s Include=""%s"" />\s*" (Regex.Escape name) (Regex.Escape inc)
+    member this.Caption() =  // how will appear in solution explorer
+        match this with
+        | FolderItem(s) ->  // folder might render as multiple nodes for each path part, return caption for final one
+            Debug.Assert(s.EndsWith("\\"), "folders should end with slash")
+            let pathParts = s.Split([| '\\' |], StringSplitOptions.RemoveEmptyEntries)
+            pathParts.[pathParts.Length - 1]
+        | CompileItem(s) -> Path.GetFileName(s)
+        | LinkedCompileItem(inc,n) -> Path.GetFileName(n)
+        | OtherItem(name,inc) -> Path.GetFileName(inc)
+    member this.IntoFolder(folder : string) =  // return new copy of item in the folder
+        Debug.Assert(folder.EndsWith("\\"), "folders should end with slash")
+        match this with
+        | FolderItem(s) ->  
+            Debug.Assert(s.EndsWith("\\"), "folders should end with slash")
+            FolderItem(folder + s)
+        | CompileItem(s) -> CompileItem(folder + s)
+        | LinkedCompileItem(inc,n) -> LinkedCompileItem(inc, folder + n)
+        | OtherItem(name,inc) -> OtherItem(name, folder + inc)
+and (*type*) MSBuildItems =
+    | MSBuildItems of list<MSBuildItem>
+    override this.ToString() =
+        match this with
+        | MSBuildItems(l) ->
+            "<ItemGroup>\n" +
+            (l |> List.map (fun x -> x.ToString()) |> List.fold (fun acc x -> sprintf "  %s%s\n" acc x) "") +
+            "</ItemGroup>"
+    member this.AsRegexString() =
+        match this with
+        | MSBuildItems(l) ->
+            "\s*<ItemGroup>\s*" +
+            (l |> List.map (fun x -> x.AsRegexString()) |> List.fold (fun acc x -> acc + x) "") +
+            "\s*</ItemGroup>\s*"
+    member this.Items() =
+        match this with
+        | MSBuildItems(l) -> l
+        
+(*
+when first click to start drag
+        public override int GetDropInfo(out uint pdwOKEffects, out IOleDataObject ppDataObject, out IDropSource ppDropSource)
+ensure pdwOKEffects are right and return S_OK
+
+when drag onto new entity
+        public override int DragEnter(IOleDataObject pDataObject, uint grfKeyState, uint itemid, ref uint pdwEffect)
+ensure is same thing(pDataObj, itemid) being dragged, pdwEffect is properly updated
+
+not sure how differs from DragEnter...
+        public override int DragOver(uint grfKeyState, uint itemid, ref uint pdwEffect)
+ensure right pdwEffect
+
+at end of drag...
+        public override int OnBeforeDropNotify(IOleDataObject o, uint dwEffect, out int fCancelDrop)
+can prompt to save dirty dragged items... nothing to verify?
+
+        public override int OnDropNotify(int fDropped, uint dwEffects)
+unsure...
+
+        public override int Drop(IOleDataObject pDataObject, uint grfKeyState, uint itemid, ref uint pdwEffect)
+unsure...
+
+        /*internal, but public for FSharp.Project.dll*/ public DropDataType ProcessSelectionDataObject(IOleDataObject dataObject, HierarchyNode targetNode)
+called by Drop, does the actual action of adding dropped files to new location        
+
+        public override int DragLeave()
+nothing to ensure, but call if leave hierarchy or drag is canceled or finishes
+
+
+called at various times:
+                public /*protected, but public for FSharp.Project.dll*/ override HierarchyNode GetDragTargetHandlerNode()
+ensure FSharpFileNode does right thing, whatever that may be, same for folder, project
+
+        /*internal, but public for FSharp.Project.dll*/ public static DropDataType QueryDropDataType(IOleDataObject pDataObject)
+maybe ref (shortcut) versus value (real file/dir on disk)?
+
+        /*internal, but public for FSharp.Project.dll*/ public DropEffect QueryDropEffect(DropDataType dropDataType, uint grfKeyState)
+given keyboard and object type, return right effect
+
+        public /*protected internal, but public for FSharp.Project.dll*/ virtual bool CanTargetNodeAcceptDrop(uint itemId)
+can't drop onto 'references'
+*)        
+
+module LanguageServiceExtension =
+    open UnitTests.TestLib.LanguageService
+    open Salsa.Salsa
+
+    type internal ProjInfo() =
+        let mutable proj = Unchecked.defaultof<UnitTestingFSharpProjectNode>
+        let mutable createProjectHookIsEnabled = true
+        member this.Project with get() = proj and set(x) = proj <- x
+        member this.CreateProjectHookIsEnabled with get() = createProjectHookIsEnabled and set(x) = createProjectHookIsEnabled <- x
+
+    let internal ProjectSystem = 
+        let msbuild,hooks = Models.MSBuild()
+        let projectDict = new Dictionary<OpenProject,ProjInfo>()
+        { msbuild with 
+                OutOfConeFilesAreAddedAsLinks=true;
+                SupportsOutputWindowPane=true;
+                AddAssemblyReference=(fun (project, assem, specificVersion) -> 
+                    let projInfo = projectDict.[project]
+                    let referencesFolder = projInfo.Project.FindChild(ReferenceContainerNode.ReferencesNodeVirtualName) :?> ReferenceContainerNode
+                    let assem = 
+                        // mimic logic in ReferenceResolution.fs:MSBuildResolver.Resolve()
+                        if Path.IsPathRooted(assem) then 
+                            assem 
+                        elif not(assem.Contains("\\") || assem.Contains("/")) then
+                            assem
+                        else 
+                            Path.Combine(projInfo.Project.ProjectFolder, assem)
+                    let assem, isFullPath =
+                        if Path.IsPathRooted(assem) then
+                            assem, true
+                        elif assem.EndsWith(".dll", StringComparison.OrdinalIgnoreCase) || assem.EndsWith(".exe", StringComparison.OrdinalIgnoreCase) then
+                            // some unit tests pass relative paths, make them absolute
+                            Path.Combine(projInfo.Project.ProjectFolder, assem), true
+                        else
+                            assem, false  // assem is a simple/fusion name of an assembly
+                    let node = referencesFolder.CreateAssemblyReferenceNode(assem, Microsoft.VisualStudio.FSharp.ProjectSystem.AddReferenceDialogTab.BrowseTab, isFullPath)
+                    if node <> null then  // node may be null if reference was to non-existent file
+                        if node.AddReference() then
+                            // still need to add it to underlying representation (SimpleOpenProject) so that
+                            // subsequent Reload() calls will have right info
+                            projInfo.CreateProjectHookIsEnabled <- false
+                            msbuild.AddAssemblyReference(project, node.Url, specificVersion)
+                            projInfo.CreateProjectHookIsEnabled <- true
+                            ());
+                CreateProject=(fun (solution,projectBaseName)->
+                    let configChangeNotifier = ref None
+                    let projInfo = new ProjInfo()
+                    let NULL = Unchecked.defaultof<UnitTestingFSharpProjectNode>
+                    let newHooks = { 
+                        // Note: CreateProjectHook will callback MakeHierarcyHook and then InitializeProjectHook
+                        CreateProjectHook = 
+                            fun (projectFilename:string) (files:(string*BuildAction*string option) list) (references:(string*bool) list) (projReferences:string list)
+                                (disabledWarnings:string list) (defines:string list) (versionFile:string) (otherFlags:string) (otherMSBuildStuff:string) (targetFrameworkVersion : string) ->
+                                    if projInfo.CreateProjectHookIsEnabled then
+                                        hooks.CreateProjectHook projectFilename files references projReferences disabledWarnings defines versionFile otherFlags otherMSBuildStuff targetFrameworkVersion
+                                        if projInfo.Project = NULL then
+                                            ()
+                                        else
+                                            // REVIEW: this is a workaround to get everything working for now; ideally we want to implement the VS gestures below
+                                            // so that they really happen in the project system, rather than just poking the .fsproj file and then doing 
+                                            // a 'reload' each time.  But for now, this is good.
+                                            projInfo.Project.Reload()
+                        InitializeProjectHook = (fun(openProject) ->
+                            hooks.InitializeProjectHook(openProject)
+                            projectDict.Add(openProject, projInfo))
+                        MakeHierarchyHook = 
+                                        fun projdir fullname projectname ccn serviceProvider -> 
+                                            if projInfo.Project = NULL then
+                                                let p = TheTests.CreateProject(fullname, "false", ccn, serviceProvider)
+                                                projInfo.Project <- p
+                                                configChangeNotifier := Some(fun s -> ccn((p :> IVsHierarchy),s))
+                                            else
+                                                failwith "oops, did not expect MakeHierarchy to be called more than once"
+                                            projInfo.Project :> IVsHierarchy
+                        AddFileToHierarchyHook = fun filename hier -> ()
+                        BuildHook = fun projFileName target vsOutputWindowPane -> 
+                                        if projInfo.Project = NULL then
+                                            failwith "tried to build not-yet-created project"
+                                        else
+                                            let target = if target <> null then target else "Build"
+                                            projInfo.Project.BuildToOutput(target,vsOutputWindowPane) |> ignore   // force build through project system for code coverage
+                                            hooks.BuildHook projFileName target vsOutputWindowPane      // use MSBuild to build and also return MainAssembly value
+                        GetMainOutputAssemblyHook = hooks.GetMainOutputAssemblyHook                                            
+                        SaveHook = fun() -> if projInfo.Project = NULL then () else projInfo.Project.Save(null, 1, 0u) |> ignore
+                        DestroyHook = fun () ->
+                                            if projInfo.Project = NULL
+                                               then ()
+                                               else projInfo.Project.Close () |> ignore
+                                                    match projectDict |> Seq.tryFind(fun (KeyValue(k,v)) -> obj.ReferenceEquals(v, projInfo)) with
+                                                    | Some(KeyValue(k,v)) -> projectDict.Remove(k) |> ignore
+                                                    | None -> failwith "uh-oh, where was it in the dict?"
+                                                    projInfo.Project <- NULL
+                        ModifyConfigurationAndPlatformHook = fun s ->
+                            match !configChangeNotifier with
+                            | Some(ccn) -> ccn(s)
+                            | None -> ()
+                    }
+
+                    msbuild.CreateProjectWithHooks(solution,newHooks,projectBaseName));
+        }
+
+    
+
+
+      
+
+                
+
+
diff --git a/vsintegration/src/unittests/TestLib.Salsa.fs b/vsintegration/src/unittests/TestLib.Salsa.fs
new file mode 100644
index 0000000..98ce5b2
--- /dev/null
+++ b/vsintegration/src/unittests/TestLib.Salsa.fs
@@ -0,0 +1,127 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+module UnitTests.TestLib.Salsa
+
+open System
+open System.IO
+open NUnit.Framework
+open Salsa.Salsa
+open Salsa.VsOpsUtils
+open System.Text.RegularExpressions
+
+// Common asserts -------------------------------------------------------------
+
+let AssertEqualWithMessage(expected, actual, message) =
+    if expected <> actual then 
+        printf "%s" message
+        Assert.Fail(message)
+        
+let AssertEqual(expected,actual) =
+    if expected<>actual then 
+        let message = sprintf "Expected:\n%A\n\nbut got:\n%A." expected actual
+        printf "%s" message
+        Assert.Fail(message)
+        
+let AssertContainsInOrder(s:string,cs:string list) =
+    let rec containsInOrderFrom fromIndex expects =
+      match expects with
+        | [] -> ()
+        | expect :: expects ->
+            let index = s.IndexOf((expect:string),(fromIndex:int))           
+            if index = -1 then
+              Assert.Fail(sprintf "Expected:\n%s\n\nto contain:\n%s\n\nafter index: %d." s expect fromIndex)
+            else
+               printfn "At index %d seen '%s'." index expect
+            containsInOrderFrom index expects
+    containsInOrderFrom 0 cs
+    
+let AssertContains(s:string,c) =
+    if not (s.Contains(c)) then
+        printf "Expected:\n%s\n\nto contain:\n%s" s c
+        Assert.Fail()
+        
+let AssertArrayContainsPartialMatchOf(a:string array,c) =
+    let found = ref false
+    a |> Array.iter(fun s -> found := s.Contains(c) || !found)
+    if not(!found) then 
+        printfn "Expected:\n%A" a            
+        printfn "to contain\n%s" c
+        Assert.Fail()        
+            
+let AssertNotContains(s:string,c) = 
+    if (s.Contains(c)) then
+        printf "Expected:\n%s\n\nnot to not contain:\n%s." s c
+        Assert.Fail()   
+        
+let AssertMatches (r : Regex) (s:string) =
+    if not (r.IsMatch(s)) then
+        printfn "Expected regex '%s' to match '%s'." (r.ToString()) s
+        Assert.Fail()
+        
+// Like AssertMatches, but runs for every prefix of regex up to each occurence of 'c'
+// Is helpful so that, if long regex match fails, you see first prefix that fails
+let AssertMatchesRegex (c : char) (regexStr : string) (s:string) =
+    let mutable i = regexStr.IndexOf(c, 0)
+    while i <> -1 do
+        let r = regexStr.Substring(0,i)
+        let regex = new Regex(r)
+        AssertMatches regex s
+        i <- regexStr.IndexOf(c, i+1)
+        
+// Common TestFixture methods -------------------------------------------------
+
+open System.IO
+open UnitTests.TestLib.Utils
+
+// adds qualifier to the global functions
+// Non-controlled usage of these functions can easily lead to the violation of invariants in tests:
+// - modification of shared VS\solution is prohibited and the only permitted operation is CreateSingleFileProject
+// - modification of fresh VS instance is allowed, to denote that tests required fresh instance of VS add line 'use  _guard - this.WithNewVS()' at the beginning of the test
+module internal GlobalFunctions = 
+    let CreateSolution(vs) = CreateSolution(vs)
+    let CloseSolution(sol) = CloseSolution(sol)
+    let Cleanup(vs) = Cleanup(vs)
+    let AddAssemblyReference(proj, ref) = AddAssemblyReference(proj, ref)
+    let AddAssemblyReferenceEx(proj, ref, v) = AddAssemblyReferenceEx(proj, ref, v)
+    let SetProjectDefines(proj, d) = SetProjectDefines(proj, d)
+    let CreateSingleFileProject(vs, content) = CreateSingleFileProject(vs, content)
+    let CreateNamedSingleFileProject(vs, content) = CreateNamedSingleFileProject(vs, content)
+    let AddDisabledWarning(proj, warning) = AddDisabledWarning(proj, warning)
+
+// hides existing global functions - so they can be accessed only from GlobalFunctions
+[<AutoOpen>]
+module HiddenFunctions = 
+    /// this function should not be called from the global namespace
+    /// if you really need it - use qualified form: GlobalFunctions.CreateSolution
+    let CreateSolution() : unit = failwith "Should not be called"
+    /// this function should not be called from the global namespace
+    /// if you really need it - use qualified form: GlobalFunctions.CloseSolution
+    let CloseSolution() : unit= failwith "Should not be called"
+    /// this function should not be called from the global namespace
+    /// if you really need it - use qualified form: GlobalFunctions.Cleanup
+    let Cleanup() : unit= failwith "Should not be called"
+    /// this function should not be called from the global namespace
+    /// if you really need it - use qualified form: GlobalFunctions.AddAssemblyReference
+    let AddAssemblyReference() : unit= failwith "Should not be called"
+    /// this function should not be called from the global namespace
+    /// if you really need it - use qualified form: GlobalFunctions.AddAssemblyReferenceEx
+    let AddAssemblyReferenceEx() : unit= failwith "Should not be called"
+    /// this function should not be called from the global namespace
+    /// if you really need it - use qualified form: GlobalFunctions.SetProjectDefines
+    let SetProjectDefines() : unit= failwith "Should not be called"
+    /// this function should not be called from the global namespace
+    /// if you really need it - use qualified form: GlobalFunctions.CreateSingleFileProject
+    let CreateSingleFileProject() : unit = failwith "Should not be called"
+    /// this function should not be called from the global namespace
+    /// if you really need it - use qualified form: GlobalFunctions.CreateNamedSingleFileProject
+    let CreateNamedSingleFileProject() : unit = failwith "Should not be called"
+    /// this function should not be called from the global namespace
+    /// if you really need it - use qualified form: GlobalFunctions.AddDisabledWarning
+    let AddDisabledWarning() : unit = failwith "Should not be called"
+
+// Common type provider approval code
+
+let ApproveAllMockTypeProviders() =
+    ClearAllTypeProviderApprovals()      
+    for file in System.IO.Directory.EnumerateFiles(System.IO.Path.Combine(System.Environment.CurrentDirectory,@"UnitTestsResources\MockTypeProviders\")) do
+        AddTypeProviderApprovedForDevelopment(file)       
diff --git a/vsintegration/src/unittests/TestLib.Utils.fs b/vsintegration/src/unittests/TestLib.Utils.fs
new file mode 100644
index 0000000..b28dfea
--- /dev/null
+++ b/vsintegration/src/unittests/TestLib.Utils.fs
@@ -0,0 +1,355 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+namespace UnitTests.TestLib.Utils
+
+open System
+open System.IO
+open NUnit.Framework
+
+open Microsoft.VisualStudio
+
+module Asserts =
+    (* Asserts ----------------------------------------------------------------------------- *)
+    let AssertEqualMsg expected actual failureMsg =
+        if expected<>actual then 
+            let message = sprintf "Expected\n%A\nbut got\n%A\n%s" expected actual failureMsg
+            printfn "%s" message
+            Assert.Fail(message)
+    let AssertEqual expected actual =
+        if expected<>actual then 
+            let message = sprintf "Expected\n%A\nbut got\n%A" expected actual
+            printfn "%s" message
+            Assert.Fail(message)
+    let AssertNotEqual expected actual =
+        if expected=actual then 
+            let message = "Expected not equal, but were equal"
+            printfn "%s" message
+            Assert.Fail(message)
+    let AssertContains (s:string) c =
+        if not (s.Contains(c)) then
+            let message = sprintf "Expected '%s' to contain '%s'." s c
+            printfn "%s" message
+            Assert.Fail(message)
+    let ValidateOK (i:int) =
+        if not (i = VSConstants.S_OK) then
+            let message = sprintf "Expected S_OK"
+            printfn "%s" message
+            Assert.Fail(message)
+
+
+module UIStuff =
+    let SetupSynchronizationContext() =
+        Microsoft.VisualStudio.FSharp.LanguageService.UIThread.InitUnitTestingMode()
+
+module FilesystemHelpers =
+    let pid = System.Diagnostics.Process.GetCurrentProcess().Id 
+
+    /// Create a new temporary directory.
+    let rec NewTempDirectory (prefixName : String) = 
+        let tick = Environment.TickCount 
+        let dir = Path.Combine(Path.GetTempPath(), sprintf "%s-%A-%d" prefixName tick pid)
+        if Directory.Exists dir then NewTempDirectory prefixName
+        else 
+            let _ = Directory.CreateDirectory(dir)
+            dir
+       
+    /// Create a temporary filename, invoke callback with that filename, then clean up temp file.
+    let DoWithTempFile (filename : string) (f : string (*filePath*) -> 'a) = 
+        let dir = NewTempDirectory "fsc-tests"
+        let filePath = Path.Combine(dir, filename)
+        let r = f filePath
+        let rec DeleteAll dir =
+            for f in Directory.GetFiles(dir) do
+                File.Delete(f)
+            for d in Directory.GetDirectories(dir) do
+                DeleteAll(d)
+            try
+                Directory.Delete(dir)
+            with e ->
+                printfn "failed to delete temp directory %s" dir
+                printfn "  error was %s" e.Message
+                printfn "  ignoring"
+        DeleteAll(dir)
+        r
+
+module Spawn = 
+    open System
+    open System.IO
+    open System.Diagnostics
+    open System.Text
+
+    /// Set this flag to true to see spawned commands.
+    let mutable showSpawnedCommands = false
+
+    type public ProcessResults = {
+        PeakPagedMemorySize:int64
+        PeakVirtualMemorySize:int64
+        PeakWorkingSet:int64
+        PrivilegedProcessorTime:float // milliseconds
+        UserProcessorTime:float // milliseconds
+        TotalProcessorTime:float // milliseconds
+        } with
+        static member internal CreateFromProcess(proc:Process) =
+            try
+                { PeakPagedMemorySize=proc.PeakPagedMemorySize64
+                  PeakVirtualMemorySize=proc.PeakVirtualMemorySize64
+                  PeakWorkingSet=proc.PeakWorkingSet64
+                  PrivilegedProcessorTime=proc.PrivilegedProcessorTime.TotalMilliseconds
+                  UserProcessorTime=proc.UserProcessorTime.TotalMilliseconds
+                  TotalProcessorTime=proc.TotalProcessorTime.TotalMilliseconds
+                }    
+            with :? InvalidOperationException as e ->
+                // There is what appears to be an unresolvable race here. The process may exit while building the record.
+                { PeakPagedMemorySize=0L
+                  PeakVirtualMemorySize=0L
+                  PeakWorkingSet=0L
+                  PrivilegedProcessorTime=0.0
+                  UserProcessorTime=0.0
+                  TotalProcessorTime=0.0
+                }               
+        static member internal SampleProcess(proc:Process,original) = 
+            try
+                { PeakPagedMemorySize=max proc.PeakPagedMemorySize64 original.PeakPagedMemorySize
+                  PeakVirtualMemorySize=max proc.PeakVirtualMemorySize64 original.PeakVirtualMemorySize
+                  PeakWorkingSet=max proc.PeakWorkingSet64 original.PeakWorkingSet
+                  PrivilegedProcessorTime=max proc.PrivilegedProcessorTime.TotalMilliseconds original.PrivilegedProcessorTime
+                  UserProcessorTime=max proc.UserProcessorTime.TotalMilliseconds original.UserProcessorTime
+                  TotalProcessorTime=max proc.TotalProcessorTime.TotalMilliseconds original.TotalProcessorTime
+                }    
+            with :? InvalidOperationException as e ->
+                // There is what appears to be an unresolvable race here. The process may exit while building the record.
+                original
+
+    let private spawnDetailed logOutputTo logErrorTo exitWith command fmt =
+        let spawn (arguments:string) = 
+            if showSpawnedCommands then
+                printfn "%s %s" command arguments
+            let pi = ProcessStartInfo(command,arguments)
+            pi.WindowStyle <- ProcessWindowStyle.Hidden
+            pi.CreateNoWindow <- true
+            pi.UseShellExecute <- false
+            pi.WorkingDirectory <- Directory.GetCurrentDirectory()
+            pi.ErrorDialog <- false
+            pi.RedirectStandardError<-true
+            pi.RedirectStandardOutput<-true
+            use proc = new Process()
+            proc.StartInfo <- pi
+            proc.OutputDataReceived.Add(logOutputTo)
+            proc.ErrorDataReceived.Add(logErrorTo)
+            match proc.Start() with
+            | false -> 
+                failwith(sprintf "Could not start process: %s %s " command arguments)
+            | true ->
+                proc.BeginOutputReadLine()
+                proc.BeginErrorReadLine()
+                let mutable stats = ProcessResults.CreateFromProcess(proc)
+                while not(proc.WaitForExit(200)) do
+                    stats <- ProcessResults.SampleProcess(proc,stats)
+                exitWith command arguments proc.ExitCode stats
+
+        Printf.ksprintf spawn fmt  
+
+    let private expectCodeOrRaise expectedCode command arguments (exitCode:int) _ = 
+        if expectedCode<>exitCode then 
+            failwith(sprintf "%s %s exitted with code %d. Expected %d" command arguments exitCode expectedCode)
+        ()
+
+    let private expectCodeWithStatisticsOrExit expectedCode command arguments (exitCode:int) stats :ProcessResults = 
+        if expectedCode<>exitCode then 
+            failwith(sprintf "%s %s exitted with code %d. Expected %d" command arguments exitCode expectedCode)
+        stats
+
+    let private returnExitCode _ _ (exitCode:int) _= exitCode
+
+    let ignoreDataReceived(_msg:DataReceivedEventArgs) = ()
+  
+    /// Execute a command
+    let public Spawn command fmt = 
+        spawnDetailed ignoreDataReceived ignoreDataReceived (expectCodeOrRaise 0) command fmt
+
+    /// Execute a command and expect a particular result code
+    let public SpawnExpectCode expectCode command fmt = 
+        spawnDetailed ignoreDataReceived ignoreDataReceived (expectCodeOrRaise expectCode) command fmt
+
+    /// Execute the command and return the exit code
+    let public SpawnReturnExitCode command fmt = 
+        spawnDetailed ignoreDataReceived ignoreDataReceived returnExitCode command fmt
+
+    /// Execute the command a return an array of textlines for the output and error.
+    let public SpawnToTextLines command fmt = 
+        let outlock = obj()
+        let captured = ref []
+        let capture (msg:DataReceivedEventArgs) = 
+            lock outlock (fun () -> captured := msg.Data :: !captured)
+
+        let exitWithResult command arguments actualCode _ = 
+            actualCode, (!captured)|>List.rev|>Array.ofList
+
+        spawnDetailed capture capture exitWithResult command fmt
+
+    /// Execute a command and expect a particular result code. Return the processor statistics.
+    let public SpawnWithStatisticsExpectCode expectCode command fmt = 
+        spawnDetailed ignoreDataReceived ignoreDataReceived (expectCodeWithStatisticsOrExit expectCode) command fmt
+
+    let Batch batchText = 
+        let outlock = obj()
+        let captured = ref []
+        let capture (msg:DataReceivedEventArgs) = 
+            lock outlock (fun () -> captured := msg.Data :: !captured)
+
+        let exitWithResult command arguments actualCode _ = 
+            actualCode, (!captured)|>List.rev|>Array.ofList
+
+        FilesystemHelpers.DoWithTempFile
+            "$$temp-batch.cmd"
+            (fun filename->
+                File.WriteAllText(filename,batchText)
+                spawnDetailed capture capture exitWithResult filename "")
+
+
+
+    /// Zip some files
+    let Zip archiveName (files: string[]) =
+        Spawn "zip.exe" "%s %s" archiveName (String.Join(" ", files))
+
+    /// Use robocopy to mirror a directory from one place to another
+    /// NOTE: This command will delete files at the destination if they don't exist at the source
+    let RoboCopyMirror source destination =
+        let code = SpawnReturnExitCode "robocopy" "%s %s /mir" source destination
+        match code with
+        | 0 | 1 | 2 | 3 -> () // Success.
+        | _ -> 
+            printfn "Robocopy %s %s /mir exitted with code %d. Expected 0, 1, 2 or 3." source destination code
+            exit code
+
+    /// Submit a specific set of checked out files to Tfs.
+    let TfsSubmitSpecificFiles (files:string[]) comment = 
+        let files = String.Join(" ", files)
+
+        // Submit the changes
+        match SpawnToTextLines "tf_.exe" "submit %s /comment:\"%s\" /noprompt" files comment with
+        | 0,_ -> 
+            printfn "Submited files: %s" files
+        | 1,_ ->  
+            printfn "No changes detected in files: %s" files
+        | errorCode,lines ->
+            for line in lines do 
+                printfn "%s" line
+            eprintfn "tf submit returned error code %d" errorCode
+
+
+namespace TestLibrary
+  module LambdaCalculus =
+
+    exception LambdaFailure of string
+
+    module Syntax =
+      type Binder = string
+
+      type Expression = Variable of Binder
+                      | Lambda   of (Binder * Expression)
+                      | Apply    of (Expression * Expression)
+
+      let rec stringOfExpression (e : Expression) : string =
+        match e with
+        | Variable x     -> x
+        | Lambda (x, e)  -> "lambda " + x + " . " + stringOfExpression e
+        | Apply (e1, e2) -> "(" + stringOfExpression e1 + ") @ (" + stringOfExpression e2 + ")"
+
+
+    module Evaluation =
+
+      open Syntax
+
+      module Environment =
+        type Env = Map<Binder, Expression>
+
+        exception EnvironmentFailure of string
+
+        let add (g : Env)(x : Binder)(e : Expression) = Map.add x e g
+
+        let lookup (g : Env)(x : Binder) =
+          try Map.find x g
+              with _ -> raise (EnvironmentFailure <| "No binding for `" + (stringOfExpression <| Variable x) + "`.")
+
+      open Environment
+
+      exception EvalFailure = LambdaFailure
+
+      let rec eval (g : Env)(e : Expression) : Expression =
+        match e with
+        | Variable x     -> lookup g x
+        | Lambda _       -> e
+        | Apply (e1, e2) -> match eval g e1 with
+                            | Lambda (x, e) -> eval (add g x (eval g e2)) e1
+                            | _             -> raise <| EvalFailure "Unexpected operator in application; need a lambda."
+
+  module OtherTests =
+    type Point = { x : int
+                   y : int
+                 }
+
+    let showPoint (p : Point) = sprintf "(%A,%A)" p.x p.y 
+
+    type Shape (initVertices : list<Point>) =
+      let mutable vertices = initVertices
+
+      let True _  = true
+      let Id   x  = x
+
+      // using this for everything is a bit artificial, but it ought to cover
+      // quite a few patterns of members interacting
+      member this.addFilterMap (pr : Point -> bool)(f : Point -> Point)(ps : list<Point>) : unit =
+        match ps with
+        | []      -> ()
+        | p :: ps -> if pr p
+                        then vertices <- (f p) :: vertices
+                     this.addFilterMap pr f ps
+
+      member this.getVertices () = vertices
+
+      member this.clearVertices () = vertices <- []
+
+      // new vertex
+      member this.addVertex (p : Point) = this.addFilterMap True Id [p]
+
+      // swallow another shape's vertices
+      member this.subsume (s : Shape) = List.iter this.addVertex (s.getVertices ())
+
+      member this.map (f : Point -> Point) =
+        let ps = this.getVertices ()
+        this.clearVertices ()
+        this.addFilterMap True f ps
+
+      member this.transpose () =
+        let swap p =
+          { x = p.y
+            y = p.x
+          }
+        this.map swap
+
+      // okay, this is silly; just to test mutual recursion of members
+      member this.fold (f : 'a -> Point -> 'a)(acc : 'a) =
+        match this.getVertices () with
+        | []      -> acc
+        | p :: ps -> f (this.refold f acc) p
+
+      member this.refold (f : 'a -> Point -> 'a)(acc : 'a) =
+        let ps = this.getVertices ()
+        let set ps =
+          this.clearVertices ()
+          this.subsume (new Shape (ps))
+        match ps with
+        | []      -> ()
+        | _ :: ps -> set ps
+        let res = this.fold f acc
+        set ps
+        acc
+
+      static member combine (s1 : Shape)(s2 : Shape) : Shape =
+        let ps1 = s1.getVertices ()
+        let ps2 = s2.getVertices ()
+        new Shape (ps1 @ (ps2 |> List.filter (fun x -> not <| List.exists ((=) x) ps1)))
+
+
+
diff --git a/vsintegration/src/unittests/Tests.BaseLine.fs b/vsintegration/src/unittests/Tests.BaseLine.fs
new file mode 100644
index 0000000..91127f6
--- /dev/null
+++ b/vsintegration/src/unittests/Tests.BaseLine.fs
@@ -0,0 +1,58 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+namespace UnitTests.Tests
+open NUnit.Framework
+open System
+open System.IO
+open System.Diagnostics
+open UnitTests.TestLib.Utils
+open Microsoft.BuildSettings
+
+[<TestFixture>]
+type Script() = 
+#if OPEN_BUILD
+    class end
+#else
+    let replaceIfNotNull (search:string) (replace:string) (s:string) =
+        match s with
+        | null -> s
+        | s -> s.Replace(search,replace) 
+    let replaceConstants(line:string) = 
+        line
+        |> replaceIfNotNull Version.OfFile "{VersionOfFile}"
+        |> replaceIfNotNull Version.OfAssembly "{VersionOfAssembly}"
+        |> replaceIfNotNull Version.ProductBuild "{VersionOfProductBuild}"
+        |> replaceIfNotNull "4.0" "{DotNetMajorMinor}"
+        |> replaceIfNotNull "4.5" "{DotNetMajorMinor}"
+        |> replaceIfNotNull (sprintf "%s.%s" Version.Major Version.Minor) "{DotNetMajorMinor}"
+        |> replaceIfNotNull "10.0" "{VsMajorMinor}"
+        |> replaceIfNotNull "F# 3.0" "F# {FSharpCompilerVersion}"
+        |> replaceIfNotNull (Environment.GetEnvironmentVariable("ProgramFiles")) "{ProgramFiles}"
+
+    let runCheck(script:string,baseline:string) =
+        let code,lines = Spawn.Batch script
+        let combinedLines = String.Join("\r\n",lines).Trim([|'\r';'\n'|]) |> replaceConstants
+        let baseline = baseline.Trim([|'\r';'\n'|])
+        if baseline<>combinedLines then 
+            for line in lines do
+                printfn "%s" (replaceConstants line)
+            Assert.AreEqual(baseline,combinedLines)
+
+    [<Test>]
+    member public __.NetModules_Bug915449() =
+        let script = @"
+ at echo off
+echo>a.cs public class A {}
+echo>b.cs public class B {}
+echo>r.fs let a = new A()
+echo>>r.fs let b = new B()
+echo>>r.fs System.Console.WriteLine(a.GetType())
+echo>>r.fs System.Console.WriteLine(b.GetType())
+csc /nologo /t:module a.cs
+csc /nologo /t:module b.cs
+al /nologo /out:c.dll a.netmodule b.netmodule
+fsc /nologo /r:c.dll r.fs
+"
+        let baseline = @""
+        runCheck(script,baseline)
+#endif
\ No newline at end of file
diff --git a/vsintegration/src/unittests/Tests.Build.fs b/vsintegration/src/unittests/Tests.Build.fs
new file mode 100644
index 0000000..4794530
--- /dev/null
+++ b/vsintegration/src/unittests/Tests.Build.fs
@@ -0,0 +1,466 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+namespace UnitTests.Tests
+
+open NUnit.Framework
+open System
+open System.IO
+open System.Diagnostics
+open Microsoft.FSharp.Build
+open Microsoft.Build.BuildEngine
+open Microsoft.Build.Framework
+open Microsoft.Build.Utilities
+open UnitTests.TestLib.Utils.FilesystemHelpers
+
+module HandyExtensions =
+    type System.String with
+        member s.MatchesPattern(p : string) =
+            System.Text.RegularExpressions.Regex.Match(s, p) <> System.Text.RegularExpressions.Match.Empty
+        member s.AssertMatchesPattern(p : string) =
+            if not (s.MatchesPattern p) then
+                let up = System.Text.RegularExpressions.Regex.Unescape p
+                let message = sprintf "Expected\n%A\nto match pattern\n%A" s up
+                printfn "%s" message
+                Assert.Fail()
+open HandyExtensions
+
+type MyLogger(f : string -> unit) =
+    let mutable verbosity = LoggerVerbosity.Quiet
+    let mutable parameters = ""
+    interface ILogger with
+        member mylogger.Initialize(eventSource : IEventSource) =
+            let onCustomEvent (e : CustomBuildEventArgs) = f e.Message
+            eventSource.CustomEventRaised.Add onCustomEvent
+            ()
+        member mylogger.Verbosity = verbosity
+        member mylogger.set_Verbosity x = verbosity <- x
+        member mylogger.Parameters = parameters
+        member mylogger.set_Parameters x = parameters <- x
+        member mylogger.Shutdown() = ()
+
+type FauxHostObject() =
+    let mutable myFlags : string[] = null
+    let mutable mySources : string[] = null
+    member x.Compile(compile:System.Converter<int,int>, flags:string[], sources:string[]) = 
+        myFlags <- flags        
+        mySources <- sources
+        0
+    member x.Flags = myFlags
+    member x.Sources = mySources
+    interface ITaskHost
+        // no members
+
+[<TestFixture>]
+type Build() = 
+    (* Asserts ----------------------------------------------------------------------------- *)
+    let AssertEqual expected actual =
+        if expected<>actual then 
+            let message = sprintf "Expected\n%A\nbut got\n%A" expected actual
+            printfn "%s" message
+            Assert.Fail(message)
+
+    let MakeTaskItem (itemSpec : string) = new TaskItem(itemSpec) :> ITaskItem
+ 
+    /// Called per test
+    [<SetUp>]
+    member this.Setup() =
+        ()
+        
+    [<TearDown>]
+    member this.TearDown() =
+        ()
+
+    [<Test>]
+    member public this.MissingToolPathError() =
+        let tool = new Microsoft.FSharp.Build.Fsc()
+        tool.ToolPath <- ""
+        try
+            let p = tool.InternalGenerateFullPathToTool()
+            Assert.Fail("should not succeed")
+        with e -> 
+            e.Message.AssertMatchesPattern("ToolPath is unknown; specify the path to fsc.exe as the ToolPath property.")
+        
+    [<Test>]
+    member public this.TestCodePage() =
+        let tool = new Microsoft.FSharp.Build.Fsc()
+        printfn "By the way, the registry or app.config tool path is %s" tool.ToolPath
+        tool.CodePage <- "65001"
+        AssertEqual "65001" tool.CodePage 
+        let cmd = tool.InternalGenerateCommandLineCommands()
+        printfn "cmd=\"%s\"" cmd
+        AssertEqual "--codepage:65001 --optimize+ --warnaserror:76 --fullpaths --flaterrors --highentropyva-" cmd
+
+    [<Test>]
+    member public this.TestDebugSymbols() =
+        let tool = new Microsoft.FSharp.Build.Fsc()
+        tool.DebugSymbols <- true
+        AssertEqual true tool.DebugSymbols
+        let cmd = tool.InternalGenerateCommandLineCommands()
+        printfn "cmd=\"%s\"" cmd
+        AssertEqual "-g --optimize+ --warnaserror:76 --fullpaths --flaterrors --highentropyva-" cmd
+
+    [<Test>]
+    member public this.TestDebugType() =
+        let tool = new Microsoft.FSharp.Build.Fsc()
+        tool.DebugType <- "pdbONly"
+        AssertEqual "pdbONly" tool.DebugType
+        let cmd = tool.InternalGenerateCommandLineCommands()
+        printfn "cmd=\"%s\"" cmd
+        AssertEqual "--debug:pdbonly --optimize+ --warnaserror:76 --fullpaths --flaterrors --highentropyva-" cmd
+
+
+    [<Test>]
+    member public this.TestDefineConstants() =
+        let tool = new Microsoft.FSharp.Build.Fsc()
+        tool.DefineConstants <- [| MakeTaskItem "FOO=3"
+                                   MakeTaskItem "BAR=4" |]
+        AssertEqual 2 tool.DefineConstants.Length 
+        let cmd = tool.InternalGenerateCommandLineCommands()
+        printfn "cmd=\"%s\"" cmd
+        AssertEqual "--define:FOO=3 --define:BAR=4 --optimize+ --warnaserror:76 --fullpaths --flaterrors --highentropyva-" cmd
+
+    [<Test>]
+    member public this.TestDisabledWarnings1() =
+        let tool = new Microsoft.FSharp.Build.Fsc()
+        tool.DisabledWarnings <- "52;109"
+        AssertEqual "52;109" tool.DisabledWarnings
+        let cmd = tool.InternalGenerateCommandLineCommands()
+        printfn "cmd=\"%s\"" cmd
+        AssertEqual "--optimize+ --nowarn:52,109 --warnaserror:76 --fullpaths --flaterrors --highentropyva-" cmd
+
+    [<Test>]
+    member public this.TestDisabledWarnings2() =
+        let tool = new Microsoft.FSharp.Build.Fsc()
+        tool.DisabledWarnings <- ";"  // e.g. someone may have <NoWarn>$(NoWarn);$(SomeOtherVar)</NoWarn> and both vars are empty
+        AssertEqual ";" tool.DisabledWarnings
+        let cmd = tool.InternalGenerateCommandLineCommands()
+        printfn "cmd=\"%s\"" cmd
+        AssertEqual "--optimize+ --warnaserror:76 --fullpaths --flaterrors --highentropyva-" cmd
+        
+    [<Test>]
+    member public this.TestVersionFile() =
+        let tool = new Microsoft.FSharp.Build.Fsc()
+        tool.VersionFile <- "src/version"
+        AssertEqual "src/version" tool.VersionFile 
+        let cmd = tool.InternalGenerateCommandLineCommands()
+        printfn "cmd=\"%s\"" cmd
+        AssertEqual "--optimize+ --versionfile:src/version --warnaserror:76 --fullpaths --flaterrors --highentropyva-" cmd        
+
+    [<Test>]
+    member public this.TestDocumentationFile() =
+        let tool = new Microsoft.FSharp.Build.Fsc()
+        tool.DocumentationFile <- "foo.xml"
+        AssertEqual "foo.xml" tool.DocumentationFile 
+        let cmd = tool.InternalGenerateCommandLineCommands()
+        printfn "cmd=\"%s\"" cmd
+        AssertEqual "--doc:foo.xml --optimize+ --warnaserror:76 --fullpaths --flaterrors --highentropyva-" cmd
+
+    [<Test>]
+    member public this.TestGenerateInterfaceFile() =
+        let tool = new Microsoft.FSharp.Build.Fsc()
+        tool.GenerateInterfaceFile <- "foo.fsi"
+        AssertEqual "foo.fsi" tool.GenerateInterfaceFile 
+        let cmd = tool.InternalGenerateCommandLineCommands()
+        printfn "cmd=\"%s\"" cmd
+        AssertEqual "--sig:foo.fsi --optimize+ --warnaserror:76 --fullpaths --flaterrors --highentropyva-" cmd
+
+    [<Test>]
+    member public this.TestKeyFile() =
+        let tool = new Microsoft.FSharp.Build.Fsc()
+        tool.KeyFile <- "key.txt"
+        AssertEqual "key.txt" tool.KeyFile 
+        let cmd = tool.InternalGenerateCommandLineCommands()
+        printfn "cmd=\"%s\"" cmd
+        AssertEqual "--keyfile:key.txt --optimize+ --warnaserror:76 --fullpaths --flaterrors --highentropyva-" cmd
+        
+    [<Test>]
+    member public this.TestNoFramework() =
+        let tool = new Microsoft.FSharp.Build.Fsc()
+        tool.NoFramework <- true
+        AssertEqual true tool.NoFramework 
+        let cmd = tool.InternalGenerateCommandLineCommands()
+        printfn "cmd=\"%s\"" cmd
+        AssertEqual "--noframework --optimize+ --warnaserror:76 --fullpaths --flaterrors --highentropyva-" cmd
+        
+    [<Test>]
+    member public this.TestOptimize() =
+        let tool = new Microsoft.FSharp.Build.Fsc()
+        tool.Optimize <- false
+        AssertEqual false tool.Optimize 
+        let cmd = tool.InternalGenerateCommandLineCommands()
+        printfn "cmd=\"%s\"" cmd
+        AssertEqual cmd "--optimize- --warnaserror:76 --fullpaths --flaterrors --highentropyva-"
+
+    [<Test>]
+    member public this.TestTailcalls() =
+        let tool = new Microsoft.FSharp.Build.Fsc()
+        tool.Tailcalls <- true
+        AssertEqual true tool.Tailcalls
+        let cmd = tool.InternalGenerateCommandLineCommands()
+        printfn "cmd=\"%s\"" cmd
+        // REVIEW we don't put the default, is that desired?
+        AssertEqual "--optimize+ --warnaserror:76 --fullpaths --flaterrors --highentropyva-" cmd
+
+    [<Test>]
+    member public this.TestOtherFlags() =
+        let tool = new Microsoft.FSharp.Build.Fsc()
+        tool.OtherFlags <- "--yadda yadda"
+        AssertEqual "--yadda yadda" tool.OtherFlags 
+        let cmd = tool.InternalGenerateCommandLineCommands()
+        printfn "cmd=\"%s\"" cmd
+        AssertEqual "--optimize+ --warnaserror:76 --fullpaths --flaterrors --highentropyva- --yadda yadda" cmd
+
+    [<Test>]
+    member public this.TestOutputAssembly() =
+        let tool = new Microsoft.FSharp.Build.Fsc()
+        tool.OutputAssembly <- "oUt.dll"
+        AssertEqual "oUt.dll" tool.OutputAssembly 
+        let cmd = tool.InternalGenerateCommandLineCommands()
+        printfn "cmd=\"%s\"" cmd
+        AssertEqual "-o:oUt.dll --optimize+ --warnaserror:76 --fullpaths --flaterrors --highentropyva-" cmd
+
+    [<Test>]
+    member public this.TestPdbFile() =
+        let tool = new Microsoft.FSharp.Build.Fsc()
+        tool.PdbFile <- "out.pdb"
+        AssertEqual "out.pdb" tool.PdbFile 
+        let cmd = tool.InternalGenerateCommandLineCommands()
+        printfn "cmd=\"%s\"" cmd
+        AssertEqual "--optimize+ --pdb:out.pdb --warnaserror:76 --fullpaths --flaterrors --highentropyva-" cmd
+
+    [<Test>]
+    member public this.TestPlatform1() =
+        let tool = new Microsoft.FSharp.Build.Fsc()
+        tool.Platform <- "x64"
+        AssertEqual "x64" tool.Platform 
+        let cmd = tool.InternalGenerateCommandLineCommands()
+        printfn "cmd=\"%s\"" cmd
+        AssertEqual "--optimize+ --platform:x64 --warnaserror:76 --fullpaths --flaterrors --highentropyva-" cmd
+
+    [<Test>]
+    member public this.TestPlatform2() =
+        let tool = new Microsoft.FSharp.Build.Fsc()
+        tool.Platform <- "itanium"
+        AssertEqual "itanium" tool.Platform 
+        let cmd = tool.InternalGenerateCommandLineCommands()
+        printfn "cmd=\"%s\"" cmd
+        AssertEqual "--optimize+ --platform:Itanium --warnaserror:76 --fullpaths --flaterrors --highentropyva-" cmd
+
+    [<Test>]
+    member public this.TestPlatform3() =
+        let tool = new Microsoft.FSharp.Build.Fsc()
+        tool.Platform <- "x86"
+        AssertEqual "x86" tool.Platform 
+        let cmd = tool.InternalGenerateCommandLineCommands()
+        printfn "cmd=\"%s\"" cmd
+        AssertEqual "--optimize+ --platform:x86 --warnaserror:76 --fullpaths --flaterrors --highentropyva-" cmd
+        
+    [<Test>]
+    member public this.TestReferences() =
+        let tool = new Microsoft.FSharp.Build.Fsc()
+        let dll = "c:\\sd\\staging\\tools\\nunit\\nunit.framework.dll"
+        tool.References <- [| MakeTaskItem dll |]
+        AssertEqual 1 tool.References.Length 
+        let cmd = tool.InternalGenerateCommandLineCommands()
+        printfn "cmd=\"%s\"" cmd
+        AssertEqual ("--optimize+ -r:" + dll + " --warnaserror:76 --fullpaths --flaterrors --highentropyva-") cmd
+        
+    [<Test>]
+    member public this.TestReferencePath() =
+        let tool = new Microsoft.FSharp.Build.Fsc()
+        let path = "c:\\sd\\staging\\tools\\nunit\\;c:\\Foo"
+        tool.ReferencePath <- path
+        AssertEqual path tool.ReferencePath 
+        let cmd = tool.InternalGenerateCommandLineCommands()
+        printfn "cmd=\"%s\"" cmd
+        AssertEqual ("--optimize+ --lib:c:\\sd\\staging\\tools\\nunit\\,c:\\Foo --warnaserror:76 --fullpaths --flaterrors --highentropyva-") cmd
+        
+    [<Test>]
+    member public this.TestReferencePathWithSpaces() =
+        let tool = new Microsoft.FSharp.Build.Fsc()
+        let path = "c:\\program files;c:\\sd\\staging\\tools\\nunit;c:\\Foo"
+        tool.ReferencePath <- path
+        AssertEqual path tool.ReferencePath 
+        let cmd = tool.InternalGenerateCommandLineCommands()
+        printfn "cmd=\"%s\"" cmd
+        AssertEqual ("--optimize+ --lib:\"c:\\program files\",c:\\sd\\staging\\tools\\nunit,c:\\Foo --warnaserror:76 --fullpaths --flaterrors --highentropyva-") cmd
+
+    [<Test>]
+    member public this.TestResources() =
+        let tool = new Microsoft.FSharp.Build.Fsc()
+        tool.Resources <- [| MakeTaskItem "Foo.resources" |]
+        AssertEqual 1 tool.Resources.Length 
+        let cmd = tool.InternalGenerateCommandLineCommands()
+        printfn "cmd=\"%s\"" cmd
+        AssertEqual "--optimize+ --resource:Foo.resources --warnaserror:76 --fullpaths --flaterrors --highentropyva-" cmd
+
+    [<Test>]
+    member public this.TestSources() =
+        let tool = new Microsoft.FSharp.Build.Fsc()
+        let src = "foo.fs"
+        let iti = MakeTaskItem src
+        tool.Sources <- [| iti; iti |]
+        AssertEqual 2 tool.Sources.Length 
+        let cmd = tool.InternalGenerateCommandLineCommands()
+        printfn "cmd=\"%s\"" cmd
+        let expect = "--optimize+ --warnaserror:76 --fullpaths --flaterrors --highentropyva- " + src + " " + src
+        AssertEqual expect cmd
+        ()
+
+    [<Test>]
+    member public this.TestTargetType1() =
+        let tool = new Microsoft.FSharp.Build.Fsc()
+        tool.TargetType <- "Library"
+        AssertEqual "Library" tool.TargetType 
+        let cmd = tool.InternalGenerateCommandLineCommands()
+        printfn "cmd=\"%s\"" cmd
+        AssertEqual "--optimize+ --target:library --warnaserror:76 --fullpaths --flaterrors --highentropyva-" cmd
+
+    [<Test>]
+    member public this.TestTargetType2() =
+        let tool = new Microsoft.FSharp.Build.Fsc()
+        tool.TargetType <- "Winexe"
+        AssertEqual "Winexe" tool.TargetType 
+        let cmd = tool.InternalGenerateCommandLineCommands()
+        printfn "cmd=\"%s\"" cmd
+        AssertEqual "--optimize+ --target:winexe --warnaserror:76 --fullpaths --flaterrors --highentropyva-" cmd
+
+    [<Test>]
+    member public this.TestTargetType3() =
+        let tool = new Microsoft.FSharp.Build.Fsc()
+        tool.TargetType <- "Module"
+        AssertEqual "Module" tool.TargetType 
+        let cmd = tool.InternalGenerateCommandLineCommands()
+        printfn "cmd=\"%s\"" cmd
+        AssertEqual "--optimize+ --target:module --warnaserror:76 --fullpaths --flaterrors --highentropyva-" cmd
+
+    [<Test>]
+    member public this.TestUtf8Output() =
+        let tool = new Microsoft.FSharp.Build.Fsc()
+        tool.Utf8Output <- true
+        let cmd = tool.InternalGenerateCommandLineCommands()
+        printfn "cmd=\"%s\"" cmd
+        AssertEqual "--optimize+ --warnaserror:76 --utf8output --fullpaths --flaterrors --highentropyva-" cmd
+        
+    [<Test>]
+    member public this.TestWin32Res() =
+        let tool = new Microsoft.FSharp.Build.Fsc()
+        tool.Win32ResourceFile <- "foo.res"
+        let cmd = tool.InternalGenerateCommandLineCommands()
+        printfn "cmd=\"%s\"" cmd
+        AssertEqual "--optimize+ --warnaserror:76 --win32res:foo.res --fullpaths --flaterrors --highentropyva-" cmd
+        
+    [<Test>]
+    member public this.TestWin32Manifest() =
+        let tool = new Microsoft.FSharp.Build.Fsc()
+        tool.Win32ManifestFile <- "foo.manifest"
+        let cmd = tool.InternalGenerateCommandLineCommands()
+        printfn "cmd=\"%s\"" cmd
+        AssertEqual "--optimize+ --warnaserror:76 --win32manifest:foo.manifest --fullpaths --flaterrors --highentropyva-" cmd 
+
+    [<Test>]
+    member public this.TestHighEntropyVA() =
+        let tool = new Microsoft.FSharp.Build.Fsc()
+        tool.HighEntropyVA <- true
+        let cmd = tool.InternalGenerateCommandLineCommands()
+        printfn "cmd=\"%s\"" cmd
+        AssertEqual "--optimize+ --warnaserror:76 --fullpaths --flaterrors --highentropyva+" cmd 
+
+
+    [<Test>]
+    member public this.TestSubsystemVersion() =
+        let tool = new Microsoft.FSharp.Build.Fsc()
+        tool.SubsystemVersion <- "6.02"
+        let cmd = tool.InternalGenerateCommandLineCommands()
+        printfn "cmd=\"%s\"" cmd
+        AssertEqual "--optimize+ --warnaserror:76 --fullpaths --flaterrors --subsystemversion:6.02 --highentropyva-" cmd 
+
+    [<Test>]
+    member public this.TestAllCombo() =
+        let tool = new Microsoft.FSharp.Build.Fsc()
+        tool.CodePage <- "65001"
+        tool.DebugSymbols <- true
+        tool.DebugType <- "full"
+        tool.DefineConstants <- [| MakeTaskItem "FOO=3"
+                                   MakeTaskItem "BAR=4" |]
+        tool.DisabledWarnings <- "52 109"
+        tool.VersionFile <- "src/version"
+        tool.DocumentationFile <- "foo.xml"
+        tool.GenerateInterfaceFile <- "foo.fsi"
+        tool.KeyFile <- "key.txt" 
+        tool.NoFramework <- true
+        tool.Optimize <- true
+        tool.Tailcalls <- true
+        tool.OtherFlags <- "--yadda:yadda --other:\"internal quote\" blah"
+        tool.OutputAssembly <- "out.dll"
+        tool.PdbFile <- "out.pdb"
+        tool.References <- [| MakeTaskItem "ref.dll"; MakeTaskItem "C:\\Program Files\\SpacesPath.dll" |]
+        tool.ReferencePath <- "c:\\foo;c:\\bar"
+        tool.Resources <- [| MakeTaskItem "MyRes.resources"; MakeTaskItem "OtherRes.resources" |]
+        tool.Sources <- [| MakeTaskItem "foo.fs"; MakeTaskItem "C:\\Program Files\\spaces.fs" |]
+        tool.WarningLevel <- "4"
+        tool.TreatWarningsAsErrors <- true
+        tool.TargetType <- "Exe"
+        tool.BaseAddress <- "0xBADF00D"
+        tool.Platform <- "AnyCPU"
+        tool.Utf8Output <- true
+        tool.VisualStudioStyleErrors <- true
+        tool.ValidateTypeProviders <- true
+        tool.SubsystemVersion <- "4.0"
+        let cmd = tool.InternalGenerateCommandLineCommands()
+        printfn "cmd=\"%s\"" cmd
+
+        let expected = "-o:out.dll --codepage:65001 -g --debug:full --noframework " +
+                       "--baseaddress:0xBADF00D " +
+                       "--define:FOO=3 --define:BAR=4 " +
+                       "--doc:foo.xml --sig:foo.fsi --keyfile:key.txt " +
+                       "--optimize+ --pdb:out.pdb --platform:anycpu " +
+                       "--resource:MyRes.resources --resource:OtherRes.resources " +
+                       "--versionfile:src/version -r:ref.dll -r:\"C:\\Program Files\\SpacesPath.dll\" --lib:c:\\foo,c:\\bar --target:exe --nowarn:52,109 " +
+                       "--warn:4 --warnaserror --warnaserror:76 --vserrors --validate-type-providers --utf8output --fullpaths --flaterrors --subsystemversion:4.0 " +
+                       "--highentropyva- --yadda:yadda --other:\"internal quote\" blah foo.fs \"C:\\Program Files\\spaces.fs\""
+                       
+        AssertEqual expected cmd
+        
+        let hostObject = new FauxHostObject()
+        tool.HostObject <- hostObject
+        tool.InternalExecuteTool("", "", "") |> ignore
+        let expectedFlags = [|
+            "-o:out.dll"
+            "--codepage:65001"
+            "-g"
+            "--debug:full"
+            "--noframework"
+            "--baseaddress:0xBADF00D"
+            "--define:FOO=3"
+            "--define:BAR=4"
+            "--doc:foo.xml"
+            "--sig:foo.fsi" 
+            "--keyfile:key.txt"
+            "--optimize+"
+            "--pdb:out.pdb"
+            "--platform:anycpu"
+            "--resource:MyRes.resources"
+            "--resource:OtherRes.resources"
+            "--versionfile:src/version"
+            "-r:ref.dll" 
+            "-r:C:\\Program Files\\SpacesPath.dll"  // note no internal quotes
+            "--lib:c:\\foo,c:\\bar"
+            "--target:exe"
+            "--nowarn:52,109"
+            "--warn:4"
+            "--warnaserror"
+            "--warnaserror:76"
+            "--vserrors"
+            "--validate-type-providers"
+            "--utf8output"
+            "--fullpaths"
+            "--flaterrors"
+            "--subsystemversion:4.0"
+            "--highentropyva-"
+            "--yadda:yadda"
+            "--other:internal quote" // note stripped internal quotes
+            "blah" |]
+        AssertEqual expectedFlags hostObject.Flags 
+        let expectedSources = [| "foo.fs"; "C:\\Program Files\\spaces.fs" |]
+        AssertEqual expectedSources hostObject.Sources
\ No newline at end of file
diff --git a/vsintegration/src/unittests/Tests.InternalCollections.fs b/vsintegration/src/unittests/Tests.InternalCollections.fs
new file mode 100644
index 0000000..709ce29
--- /dev/null
+++ b/vsintegration/src/unittests/Tests.InternalCollections.fs
@@ -0,0 +1,216 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+namespace UnitTests.Tests.InternalCollections
+
+open System
+open System.IO
+open NUnit.Framework
+open Internal.Utilities.Collections
+       
+                
+[<TestFixture>] 
+type MruCache = 
+    new() = { }        
+
+    member private rb.NumToString = function
+        | 0->"Zero"  | 1->"One"
+        | 2->"Two"   | 3->"Three"
+        | 4->"Four"  | 5->"Five"
+        | 6->"Six"   | 7->"Seven"
+        | 8->"Eight" | 9->"Nine"
+        | _ -> failwith "Out of range"
+        
+    member private rb.NumToStringBox n = box (rb.NumToString n)
+
+    [<Test>]
+    member public rb.Basic() = 
+        let m = new MruCache<int,string>(3, rb.NumToString, (fun (x,y) -> x = y))
+        let s = m.Get(5)
+        Assert.IsTrue("Five"=s)
+        let s = m.Get(6)
+        Assert.IsTrue("Six"=s)
+        let s = m.Get(7)
+        Assert.IsTrue("Seven"=s)
+        let s = m.Get(8)
+        Assert.IsTrue("Eight"=s)
+        let (i,s) = Option.get m.MostRecent
+        Assert.AreEqual(8,i)
+        Assert.IsTrue("Eight"=s)
+        ()
+
+    [<Test>]
+    member public rb.MostRecentOfEmpty() = 
+        let m = new MruCache<int,string>(3, rb.NumToString, (fun (x,y) -> x = y))
+        match m.MostRecent with
+            | Some _->failwith "Expected None"
+            | None->()
+
+
+    [<Test>]
+    member public rb.SetAlternate() = 
+        let m = new MruCache<int,string>(3, rb.NumToString, (fun (x,y) -> x = y))
+        m.SetAlternate(2,"Banana")
+        let (i,s) = Option.get m.MostRecent
+        Assert.AreEqual(2,i)
+        Assert.IsTrue("Banana"=s)
+            
+    member private rb.AddBanana(m:MruCache<int,obj>) = 
+        let banana = new obj()
+        m.SetAlternate(2,banana)
+        let s = m.Get(2)
+        Assert.AreEqual(banana,s)                    
+            
+    [<Test>]
+    member public rb.CacheDepthIsHonored() = 
+        let m = new MruCache<int,obj>(3, rb.NumToStringBox, (fun (x,y) -> x = y))
+        rb.AddBanana(m) // Separate function to keep 'banana' out of registers
+        let _ = m.Get(3)
+        let _ = m.Get(4)
+        let _ = m.Get(5)
+        GC.Collect()
+        let s = m.Get(2)
+        Assert.IsTrue("Two"=downcast s)
+            
+    [<Test>]
+    member public rb.SubsumptionIsHonored() = 
+        let PairToString (s,n) = rb.NumToString n
+        let AreSameForSubsumption((s1,n1),(s2,n2)) = n1=n2
+                
+        let m = new MruCache<string*int,string>(3, PairToString, (fun (x,y) -> x = y), areSameForSubsumption=AreSameForSubsumption)
+        m.SetAlternate(("x",2),"Banana")
+        let s = m.Get (("x",2))
+        Assert.IsTrue("Banana"=s, "Check1")                                      
+        let s = m.Get (("y",2))
+        Assert.IsTrue("Two"=s, "Check2")                                      
+        let s = m.Get (("x",2))
+        Assert.IsTrue("Two"=s, "Check3") // Not banana because it was subsumed
+
+    [<Test>]
+    member public rb.OnDiscardIsHonored() = 
+        
+        let AreSameForSubsumption((s1,n1),(s2,n2)) = s1=s2
+                
+        let discarded = ref [] 
+        let m = new MruCache<string*int,string>(compute=fst, areSame=(fun (x,y) -> x = y), areSameForSubsumption=AreSameForSubsumption, keepStrongly=2, keepMax=2, onDiscard=(fun s -> discarded := s :: !discarded))
+        m.SetAlternate(("x",1),"Banana") // no discard
+        printfn "discarded = %A" discarded.Value
+        Assert.IsTrue(discarded.Value = [], "Check1")                                      
+        m.SetAlternate(("x",2),"Apple") // forces discard of x --> Banana
+        printfn "discarded = %A" discarded.Value
+        Assert.IsTrue(discarded.Value = ["Banana"], "Check2")                                      
+        let s = m.Get (("x",3))
+        printfn "discarded = %A" discarded.Value
+        Assert.IsTrue(discarded.Value = ["Apple"; "Banana"], "Check3")                                      
+        let s = m.Get (("y",4))
+        printfn "discarded = %A" discarded.Value
+        Assert.IsTrue(discarded.Value = ["Apple"; "Banana"], "Check4")                                      
+        let s = m.Get (("z",5)) // forces discard of x --> Bananas
+        printfn "discarded = %A" discarded.Value
+        Assert.IsTrue(discarded.Value = ["x"; "Apple";"Banana"], "Check5")                                      
+        let s = m.Get (("w",6)) // forces discard of y
+        printfn "discarded = %A" discarded.Value
+        Assert.IsTrue(discarded.Value = ["y";"x";"Apple";"Banana"], "Check6")                                      
+            
+[<TestFixture>] 
+type AgedLookup() = 
+    let mutable hold197 : byte [] = null
+    let mutable hold198 : byte [] = null
+    let mutable hold199 : byte [] = null
+
+    let WeakRefTest n = 
+        let al = AgedLookup<int,byte[]>(n, (fun (x,y) -> x = y))
+            
+        let AssertCached(i,o:byte array) = 
+            match al.TryPeekKeyValue(i) with
+            | Some(_,x) -> Assert.IsTrue(obj.ReferenceEquals(o,x), sprintf "Object in cache (%d) does not agree with expectation (%d)" x.[0] i)
+            | None -> Assert.IsTrue(false, "Object fell out of cache")
+                
+        let AssertExistsInCached(i) = 
+            match al.TryPeekKeyValue(i) with
+            | Some _ -> ()
+            | None -> Assert.IsTrue(false, "Object fell out of cache")                
+                
+        let AssertNotCached(i) = 
+            match al.TryPeekKeyValue(i) with
+            | Some _ -> Assert.IsTrue(false, "Expected key to have fallen out of cache")     
+            | None -> ()         
+            
+        let f() =
+            try
+                // Add some large objects
+                for i in 150..199 do 
+                    let mutable large : byte array = Array.create (5 * 1024 * 1024) (byte i)
+                    if i = 197 then hold197<-large
+                    if i = 198 then hold198<-large
+                    if i = 199 then hold199<-large
+                    al.Put(i, large)
+                    large<-null
+            finally
+                printfn "ensure these objects are never on the stack of the top-level test"
+        f()    
+
+        // At this point, item 0 should be long gone.
+        AssertNotCached(0)
+            
+        // Also, hold197-hold199 may be strongly held depending on the value of 'n' passed to this test.
+        GC.Collect() 
+        let f() =
+            try
+                AssertCached(197,hold197)
+                AssertCached(198,hold198)
+                AssertCached(199,hold199)
+            finally
+                printfn "ensure these objects are never on the stack of the top-level test"
+        f()            
+
+        // Release a strongly held item (unless n=0) and see that it hasn't fallen out
+        hold199 <- null
+        GC.Collect()
+        let f() =
+            try
+                AssertCached(197,hold197)
+                AssertCached(198,hold198)
+                if n>0 then 
+                    AssertExistsInCached(199) // hold19 should be held
+                else 
+                    AssertNotCached(199)
+            finally
+                printfn "ensure these objects are never on the stack of the top-level test"
+        f()            
+            
+        // Release a strongly held item (unless n<=1) and see that it hasn't fallen out
+        hold198 <- null
+        GC.Collect()
+        let f() =
+            try
+                AssertCached(197,hold197)
+                if n>1 then 
+                    AssertExistsInCached(198) // hold198 should be held
+                else 
+                    AssertNotCached(198)         
+            finally
+                printfn "ensure these objects are never on the stack of the top-level test"
+        f()            
+            
+        // Release a strongly held item (unless n<=2) and see that it hasn't fallen out
+        hold197 <- null
+        GC.Collect()
+        let f() =
+            try
+                if n>2 then 
+                    AssertExistsInCached(197) // hold197 should be held
+                else
+                    AssertNotCached(197)      
+            finally
+                printfn "ensure these objects are never on the stack of the top-level test"
+        f()            
+            
+        // Let go of everything else.
+        al.Clear()
+        GC.Collect()
+        
+        
+    [<Test>] member public rb.WeakRef0() = WeakRefTest 0
+    [<Test>] member public rb.WeakRef1() = WeakRefTest 1
+    [<Test>] member public rb.WeakRef2() = WeakRefTest 2
+    [<Test>] member public rb.WeakRef3() = WeakRefTest 3
diff --git a/vsintegration/src/unittests/Tests.LanguageService.Colorizer.fs b/vsintegration/src/unittests/Tests.LanguageService.Colorizer.fs
new file mode 100644
index 0000000..e0238c3
--- /dev/null
+++ b/vsintegration/src/unittests/Tests.LanguageService.Colorizer.fs
@@ -0,0 +1,1077 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+namespace UnitTests.Tests.LanguageService
+
+open System
+open NUnit.Framework
+open Salsa.Salsa
+open Salsa.VsOpsUtils
+open UnitTests.TestLib.Salsa
+open UnitTests.TestLib.Utils
+open UnitTests.TestLib.LanguageService
+
+type ColorizerTests()  = 
+    inherit LanguageServiceBaseTests()
+
+    //Marker At The End Helper Functions
+    member private this.VerifyColorizerAtEndOfMarker(fileContents : string, marker : string, tokenType : TokenType) =
+        let (solution, project, file) = this.CreateSingleFileProject(fileContents)
+        MoveCursorToEndOfMarker(file, marker)
+        AssertEqual(tokenType, GetTokenTypeAtCursor(file))
+
+    //Marker At The Start Helper Function
+    member private this.VerifyColorizerAtStartOfMarker(fileContents : string, marker : string, tokenType : TokenType) =
+        let (solution, project,file) = this.CreateSingleFileProject(fileContents)
+        MoveCursorToStartOfMarker(file, marker)
+        AssertEqual(tokenType, GetTokenTypeAtCursor(file))
+
+    [<Test>]
+    member this.``Comment.SingleLine``() = 
+        this.VerifyColorizerAtEndOfMarker(
+            fileContents =  """
+                let simplefunction x y = x + y // Test1SimpleComment""",
+            marker = "// Test1", 
+            tokenType = TokenType.Comment)
+      
+    [<Test>]
+    member this.``Conment.SingleLine.MultiConments``() = 
+        this.VerifyColorizerAtEndOfMarker(
+            fileContents =  """
+                let x = // Test2SimpleComment // 1""",
+            marker = "// Test2", 
+            tokenType = TokenType.Comment)
+
+    [<Test>]
+    member this.``Comment.MultiLine.AfterAnExpression``() = 
+        this.VerifyColorizerAtEndOfMarker(
+            fileContents = """
+                let mutliLine x = 5(* Test1MultiLine
+                     Test2MultiLine <@@asdf@@>
+                Test3MultiLine*) + 1(*Test4*)""",
+            marker = "Test1",
+            tokenType = TokenType.Comment) 
+            
+    [<Test>]
+    member this.``Comment.MultiLine.WithLineBreakAndATab``() = 
+        this.VerifyColorizerAtEndOfMarker(
+            fileContents = """
+                let mutliLine x = 5(* Test1MultiLine
+                     Test2MultiLine <@@asdf@@>
+                Test3MultiLine*) + 1(*Test4*)
+                """,
+            marker = "Test2",
+            tokenType = TokenType.Comment)  
+
+    [<Test>]
+    member this.``Comment.MultiLine.WithLineBreakAfterQuotExp``() = 
+        this.VerifyColorizerAtEndOfMarker(
+            fileContents = """
+                let mutliLine x = 5(* Test1MultiLine
+                     Test2MultiLine <@@asdf@@>
+                Test3MultiLine*) + 1(*Test4*)
+                """,
+            marker = "Test3",
+            tokenType = TokenType.Comment)  
+
+    [<Test>]
+    member this.``Comment.MultiLine.AfterANumber``() =
+        this.VerifyColorizerAtStartOfMarker(
+            fileContents = """
+                let mutliLine x = 5(* Test1MultiLine
+                     Test2MultiLine <@@asdf@@>
+                Test3MultiLine*) + 1(*Test4*)
+                """,
+            marker = "1(*Test4*)",
+            tokenType = TokenType.Number) 
+
+    [<Test>]
+    member this.``Comment.Nested.Nested01``() =
+        this.VerifyColorizerAtEndOfMarker(
+            fileContents = """
+                (* L1Nesting
+                    (* L2Nesting
+                        (* L3 Nesting
+                            let l3code = 3
+                        *)
+                        let l2code = 2
+                    *)
+                    let l1code = 1
+                *)
+                let l0code = 0
+                """,
+            marker = "let l3",
+            tokenType = TokenType.Comment)
+
+    [<Test>]
+    member this.``Comment.Nested.Nested02``() = 
+        this.VerifyColorizerAtEndOfMarker(
+            fileContents = """
+                (* L1Nesting
+                    (* L2Nesting
+                        (* L3 Nesting
+                            let l3code = 3
+                        *)
+                        let l2code = 2
+                    *)
+                    let l1code = 1
+                *)
+                let l0code = 0
+                """,
+            marker = "let l2",
+            tokenType = TokenType.Comment)
+            
+    [<Test>]
+    member this.``Comment.Nested.Nested03``() = 
+        this.VerifyColorizerAtEndOfMarker(
+            fileContents = """
+                (* L1Nesting
+                    (* L2Nesting
+                        (* L3 Nesting
+                            let l3code = 3
+                        *)
+                        let l2code = 2
+                    *)
+                    let l1code = 1
+                *)
+                let l0code = 0
+                """,
+            marker = "let l1",
+            tokenType = TokenType.Comment)   
+            
+    [<Test>]
+    member this.``Comment.Nested.IdentAfterNestedComments``() = 
+        this.VerifyColorizerAtEndOfMarker(
+            fileContents = """
+                (* L1Nesting
+                    (* L2Nesting
+                        (* L3 Nesting
+                            let l3code = 3
+                        *)
+                        let l2code = 2
+                    *)
+                    let l1code = 1
+                *)
+                let l0code = 0
+                """,
+            marker = "let l0",
+            tokenType = TokenType.Identifier)                                         
+
+    [<Test>]
+    member this.``Comment.CommentInString``() = 
+        this.VerifyColorizerAtEndOfMarker(
+            fileContents = """
+                let commentsInString = "...(*test1_comment_in_string_literal*)..."
+                )""",
+            marker = "test1",
+            tokenType = TokenType.String) 
+  
+    [<Test>]
+    member this.``Comment.StringInComment``() = 
+        this.VerifyColorizerAtEndOfMarker(
+            fileContents = """
+                (*
+                let commentsInString2 = "...*)test2_stringliteral_in_comment(*..."
+                *)""",
+            marker = "test2",
+            tokenType = TokenType.Comment)
+
+    [<Test>]
+    member this.``Comment.Unterminated.KeywordBeforeComment``() = 
+        this.VerifyColorizerAtStartOfMarker(
+            fileContents = """
+                type IPeekPoke = interface(*ML Comment Start
+                  abstract member Peek: unit -> int
+                  abstract member Poke: int -> unit
+                end
+                """,
+            marker = "face(*ML Comment Start",
+            tokenType = TokenType.Keyword) 
+            
+    [<Test>]
+    member this.``Comment.Unterminated.KeywordInComment``() = 
+        this.VerifyColorizerAtStartOfMarker(
+            fileContents = """
+                type IPeekPoke = interface(*ML Comment Start
+                  abstract member Peek: unit -> int
+                  abstract member Poke: int -> unit
+                end
+
+                type wodget = class
+                  val mutable state: int 
+                  interface IPeekPoke with(*Few Lines Later2*)
+                    member x.Poke(n) = x.state <- x.state + n
+                    member x.Peek() = x.state 
+                  end
+                end(*Few Lines Later3*)""",
+            marker = "with(*Few Lines Later2*)",
+            tokenType = TokenType.Comment)  
+            
+    [<Test>]
+    member this.``Comment.Unterminated.NestedComments``() = 
+        this.VerifyColorizerAtStartOfMarker(
+            fileContents = """
+                type IPeekPoke = interface(*ML Comment Start
+                  abstract member Peek: unit -> int
+                  abstract member Poke: int -> unit
+                end
+
+                type wodget = class
+                  val mutable state: int 
+                  interface IPeekPoke with(*Few Lines Later2*)
+                    member x.Poke(n) = x.state <- x.state + n
+                    member x.Peek() = x.state 
+                  end
+                  member x.HasBeenPoked = (x.state <> 0)
+                  new() = { state = 0 }
+                end(*Few Lines Later3*)""",
+            marker = "nd(*Few Lines Later3*)",
+            tokenType = TokenType.Comment) 
+
+    [<Test>]
+    member this.``String.AtEnd``() =
+        this.VerifyColorizerAtStartOfMarker(
+            fileContents = """
+                let stringone = "simple string test"(*Simple String*) """, 
+            marker = """est"(*Simple String*)""", tokenType = TokenType.String)
+
+    [<Test>]
+    member this.``String.MultiLines``() =
+        this.VerifyColorizerAtStartOfMarker(
+            fileContents = """
+                let stringtwo = "simple test(*MultiLine - First*)
+                                string test"(*MultiLine - Second*)""",
+            marker = "st(*MultiLine - First*)",
+            tokenType = TokenType.String) 
+            
+    [<Test>]
+    member this.``String.MultiLines.LineBreak``() =
+        this.VerifyColorizerAtStartOfMarker(
+            fileContents = """
+                let stringtwo = "simple test(*MultiLine - First*)
+                                string test"(*MultiLine - Second*) """,
+            marker =  "\"(*MultiLine - Second*) ",
+            tokenType = TokenType.String)
+            
+    [<Test>]
+    member this.``String.Literal``() =
+        this.VerifyColorizerAtStartOfMarker(
+            fileContents = """               
+                let stringthree = @"literal test"(*Literal String*)""",
+                            marker = """st"(*Literal String*)""",
+            tokenType = TokenType.String)                                   
+            
+    [<Test>]
+    member this.``ByteString.AtEnd``() =
+        this.VerifyColorizerAtStartOfMarker(
+            fileContents = """
+                let bytestringone = "abcdefg"B(*Byte String*)""", 
+            marker = "B(*Byte String*)", tokenType = TokenType.String)
+
+    [<Test>]
+    member this.``ByteString.MultiLines``() =
+        this.VerifyColorizerAtStartOfMarker(
+            fileContents = """
+                let bytestringtwo = "simple(*MultiLineB - First*)
+                                    string"B(*MultiLineB - Second*)""",
+            marker =  """ing"B(*MultiLineB - Second*)""",
+            tokenType = TokenType.String)
+             
+    [<Test>]
+    member this.``ByteString.Literal``() =
+        this.VerifyColorizerAtStartOfMarker(
+            fileContents = """                                  
+                let bytestringthree = @"literal"B(*Literal Byte*)""",
+            marker = """al"B(*Literal Byte*)""",
+            tokenType = TokenType.String)             
+
+    [<Test>]
+    member this.``EscapedIdentifier.word``() =
+        this.VerifyColorizerAtStartOfMarker(
+            fileContents = """let ``this is an escaped identifier 123ASDF@#$"`` = 4""",
+            marker = "`this",
+            tokenType = TokenType.Identifier)
+
+    [<Test>]
+    member this.``EscapedIdentifier.SpecialChar``() =
+        this.VerifyColorizerAtStartOfMarker(
+            fileContents = """let ``this is an escaped identifier 123ASDF@#$"`` = 4""",
+            marker = "3ASDF@#",
+            tokenType = TokenType.Identifier)
+
+    [<Test>]
+    member this.``EscapedIdentifier.EscapeChar``() =
+        this.VerifyColorizerAtStartOfMarker(
+            fileContents = """let ``this is an escaped identifier 123ASDF@#$"`` = 4""",
+            marker = "\"``",
+            tokenType = TokenType.Identifier)
+
+    /// Regression for 3609 - Colorizer: __SOURCE__ and others colorized as a string
+    [<Test>]
+    member this.``PredefinedIdentifier.SOURCE_DIRECTORY``() = 
+        this.VerifyColorizerAtStartOfMarker(
+            fileContents = """
+                let x = __SOURCE_DIRECTORY__(*Test1*)""",
+            marker = "__(*Test1*)",
+            tokenType = TokenType.Keyword)
+
+    [<Test>]
+    member this.``PredefinedIdentifier.SOURCE_FILE``() = 
+        this.VerifyColorizerAtStartOfMarker(
+            fileContents = """
+                let y = __SOURCE_FILE__(*Test2*))""",
+            marker = "__(*Test2*)",
+            tokenType = TokenType.Keyword)
+
+    [<Test>]
+    member this.``PredefinedIdentifier.LINE``() = 
+        this.VerifyColorizerAtStartOfMarker(
+            fileContents = """
+                let z = __LINE__(*Test3*)""",
+            marker = "__(*Test3*)",
+            tokenType = TokenType.Keyword)
+
+    // Regression Test for FSB 3566, F# colorizer does not respect numbers 
+    [<Test>]
+    member this.``Number.InAnExpression``() =
+        this.VerifyColorizerAtStartOfMarker(
+            fileContents = """let f x = x + 9""",
+            marker = "9",
+            tokenType = TokenType.Number)
+           
+    // Regression Test for FSB 1778 - Colorization seems to be confused after parsing a comment that contains a verbatim string that contains a \
+    [<Test>]
+    member this.``Number.AfterCommentWithBackSlash``() =
+        this.VerifyColorizerAtStartOfMarker(
+            fileContents = """let f (* @"\\" *)x = x + 19(*Marker1*)""",
+            marker = "9(*Marker1*)",
+            tokenType = TokenType.Number)
+    
+    // Regression Test for FSharp1.0:2539 -- lexing @"" strings inside (* *) comments?
+    [<Test>]
+    member this.``Keyword.AfterCommentWithLexingStrings``() =
+        this.VerifyColorizerAtStartOfMarker(
+            fileContents = """
+                (*
+                let x = @"\\"
+                *)
+
+                let(*Marker1*) y = 1
+                """,
+            marker = "t(*Marker1*)",
+            tokenType = TokenType.Keyword)
+    
+    // Regression Test for FSB 1380 - Language Service colorizes anything followed by a bang as a keyword
+    [<Test>]
+    member this.``Keyword.LetBang``() =
+        this.VerifyColorizerAtStartOfMarker(
+            fileContents = """
+                let seqExpr = 
+                    seq {
+                        let! x = [1 .. 10](*Marker1*)
+                        yield! x(*Marker2*)
+                        do! - = ()(*Marker3*)
+                    }""",
+            marker = "! x = [1 .. 10](*Marker1*)",
+            tokenType = TokenType.Keyword)
+
+    [<Test>]
+    member this.``Keyword.Yield``() =
+        this.VerifyColorizerAtStartOfMarker(
+            fileContents = """
+                let seqExpr = 
+                    seq {
+                        let! x = [1 .. 10](*Marker1*)
+                        yield! x(*Marker2*)
+                        do! - = ()(*Marker3*)
+                    }""",
+            marker = "! x(*Marker2*)",
+            tokenType = TokenType.Keyword)
+
+    [<Test>]
+    member this.``Keyword.Do``() =
+        this.VerifyColorizerAtStartOfMarker(
+            fileContents = """
+                let seqExpr = 
+                    seq {
+                        let! x = [1 .. 10](*Marker1*)
+                        yield! x(*Marker2*)
+                        do! - = ()(*Marker3*)
+                    }""",
+            marker = "! - = ()(*Marker3*)",
+            tokenType = TokenType.Keyword)
+    
+    [<Test>]
+    member this.``Keyword.Invalid.Bang``() =
+        this.VerifyColorizerAtStartOfMarker(
+            fileContents = """
+                let seqExpr = 
+                    seq {
+                        foo! = true(*Marker1*)
+                    }""",
+            marker = "! = true(*Marker1*)",
+            tokenType = TokenType.Identifier)
+    
+    [<Test>]
+    [<Category("TypeProvider")>]
+    [<Category("TypeProvider.StaticParameters")>]
+    //This test case Verify that the color of const is the keyword color
+    member this.``TypeProvider.StaticParameters.Keyword.const``() =                 
+        this.VerifyColorizerAtStartOfMarker(
+            fileContents = """
+                     type foo = N1.T< const(*Marker1*) "Hello World",2>""",
+            marker = "t(*Marker1*)",
+            tokenType = TokenType.Keyword)
+
+    // Regression test for FSB 3696 - Colorization doesn't treat #if/else/endif correctly when embedded in a string literal
+    [<Test>]
+    member this.``PreProcessor.InStringLiteral01``() =
+        this.VerifyColorizerAtStartOfMarker(
+            fileContents = """
+                #if UNDEFINED
+                let x = "#elseMarker1"
+                let y = "#endifMarker2"
+                #else//Marker3
+                let x = "#elseMarker4"
+                let y = "#endifMarker5"
+                #endif""",
+            marker = "eMarker1",
+            tokenType = TokenType.InactiveCode)
+
+    [<Test>]
+    member this.``PreProcessor.InStringLiteral02``() =
+        this.VerifyColorizerAtStartOfMarker(
+            fileContents = """
+                #if UNDEFINED
+                let x = "#elseMarker1"
+                let y = "#endifMarker2"
+                #else//Marker3
+                let x = "#elseMarker4"
+                let y = "#endifMarker5"
+                #endif""",
+            marker = "fMarker2",
+            tokenType = TokenType.InactiveCode)
+  
+    [<Test>]
+    member this.``PreProcessor.ElseKeyword``() =
+        this.VerifyColorizerAtStartOfMarker(
+            fileContents = """
+                #if UNDEFINED
+                let x = "#elseMarker1"
+                let y = "#endifMarker2"
+                #else//Marker3
+                let x = "#elseMarker4"
+                let y = "#endifMarker5"
+                #endif""",
+            marker = "e//Marker3",
+            tokenType = TokenType.PreprocessorKeyword)    
+    
+    [<Test>]
+    member this.``PreProcessor.InStringLiteral03``() =
+        this.VerifyColorizerAtStartOfMarker(
+            fileContents = """
+                #if UNDEFINED
+                let x = "#elseMarker1"
+                let y = "#endifMarker2"
+                #else//Marker3
+                let x = "#elseMarker4"
+                let y = "#endifMarker5"
+                #endif""",
+            marker = "eMarker4",
+            tokenType = TokenType.String)   
+
+    [<Test>]
+    member this.``PreProcessor.InStringLiteral04``() =
+        this.VerifyColorizerAtStartOfMarker(
+            fileContents = """
+                #if UNDEFINED
+                let x = "#elseMarker1"
+                let y = "#endifMarker2"
+                #else//Marker3
+                let x = "#elseMarker4"
+                let y = "#endifMarker5"
+                #endif""",
+            marker = "fMarker5",
+            tokenType = TokenType.String)   
+       
+    // Regression test for FSHARP1.0:4279
+    [<Test>]
+    member this.``Keyword.OCaml.asr``() =
+        this.VerifyColorizerAtStartOfMarker(
+            fileContents = """
+                let foo a =
+                  match a with
+                  | Some(asr, b)  -> ()
+                  |_ -> ()""",
+            marker = "asr",
+            tokenType = TokenType.Keyword)
+
+    [<Test>]
+    member this.``Keyword.OCaml.land``() =
+        this.VerifyColorizerAtStartOfMarker(
+            fileContents = """
+                let foo a =
+                  match a with
+                  | Some(land, b)  -> ()
+                  |_ -> ()""",
+            marker = "land",
+            tokenType = TokenType.Keyword)
+
+    [<Test>]
+    member this.``Keyword.OCaml.lor``() =
+        this.VerifyColorizerAtStartOfMarker(
+            fileContents = """
+                let foo a =
+                  match a with
+                  | Some(lor, b)  -> ()
+                  |_ -> ()""",
+            marker = "lor",
+            tokenType = TokenType.Keyword)
+
+    [<Test>]
+    member this.``Keyword.OCaml.lsl``() =
+        this.VerifyColorizerAtStartOfMarker(
+            fileContents = """
+                let foo a =
+                  match a with
+                  | Some(lsl, b)  -> ()
+                  |_ -> ()""",
+            marker = "lsl",
+            tokenType = TokenType.Keyword)
+
+    [<Test>]
+    member this.``Keyword.OCaml.lsr``() =
+        this.VerifyColorizerAtStartOfMarker(
+            fileContents = """
+                let foo a =
+                  match a with
+                  | Some(lsr, b)  -> ()
+                  |_ -> ()""",
+            marker = "lsr",
+            tokenType = TokenType.Keyword)
+
+    [<Test>]
+    member this.``Keyword.OCaml.lxor``() =
+        this.VerifyColorizerAtStartOfMarker(
+            fileContents = """
+                let foo a =
+                  match a with
+                  | Some(lxor, b)  -> ()
+                  |_ -> ()""",
+            marker = "lxor",
+            tokenType = TokenType.Keyword)
+
+    [<Test>]
+    member this.``Keyword.OCaml.mod``() =
+        this.VerifyColorizerAtStartOfMarker(
+            fileContents = """
+                let foo a =
+                  match a with
+                  | Some(mod, b)  -> ()
+                  |_ -> ()""",
+            marker = "mod",
+            tokenType = TokenType.Keyword)
+
+    [<Test>]
+    member this.``Keyword.OCaml.sig``() =
+        this.VerifyColorizerAtStartOfMarker(
+            fileContents = """
+                let foo a =
+                  match a with
+                  | Some(sig, b)  -> ()
+                  |_ -> ()""",
+            marker = "sig",
+            tokenType = TokenType.Keyword)
+
+    [<Test>]
+    member this.InactiveCode() =
+        let fileContents = """
+                #if UNDEFINED
+                                    (*Inactive Code1*)let notLegit1 x = x
+                #else
+                    #if UNDEFINED
+                                    (*Inactive Code2*)let notLegit2 x = x
+                    #else
+                        #if UNDEFINED
+                                    (*Inactive Code3*)let notLegit3 x = x
+                        #else
+                            #if UNDEFINED
+                                    (*Inactive Code4*)let notLegit4 x = x            
+                            #else
+                                #if UNDEFINED
+                                    (*Inactive Code5*)let notLegit5 x = x
+                                #else
+                                      (*Active Code5*)let legitCode5 x = x
+                                #endif
+                                      (*Active Code4*)let legitCode4 x = x
+                            #endif
+                                      (*Active Code3*)let legitCode3 x = x
+                        #endif
+
+                                      (*Active Code2*)let legitCode2 x = x
+                    #endif
+                                      (*Active Code1*)let legitCode1 x = x
+                #endif
+
+                #if DEFINED
+                                      (*Active Code6*)let legitCode6 x = x
+                    #if DEFINED
+                                      (*Active Code7*)let legitCode7 x = x
+                    #else
+                                    (*Inactive Code7*)let notLegit7 x = x
+                    #endif
+                #else
+                                    (*Inactive Code6*)let notLegit6 x = x
+                #endif
+                """
+
+        let (_solution, _project, file) = this.CreateSingleFileProject(fileContents, defines = ["DEFINED"])
+        MoveCursorToEndOfMarker(file, "Active Code1*)le"); AssertEqual(TokenType.Keyword, GetTokenTypeAtCursor(file))
+        MoveCursorToEndOfMarker(file, "Active Code2*)le"); AssertEqual(TokenType.Keyword, GetTokenTypeAtCursor(file))
+        MoveCursorToEndOfMarker(file, "Active Code3*)le"); AssertEqual(TokenType.Keyword, GetTokenTypeAtCursor(file))
+        MoveCursorToEndOfMarker(file, "Active Code4*)le"); AssertEqual(TokenType.Keyword, GetTokenTypeAtCursor(file))
+        MoveCursorToEndOfMarker(file, "Active Code5*)le"); AssertEqual(TokenType.Keyword, GetTokenTypeAtCursor(file))
+        MoveCursorToEndOfMarker(file, "Active Code6*)le"); AssertEqual(TokenType.Keyword, GetTokenTypeAtCursor(file))
+        MoveCursorToEndOfMarker(file, "Active Code7*)le"); AssertEqual(TokenType.Keyword, GetTokenTypeAtCursor(file))
+
+        MoveCursorToEndOfMarker(file, "Inactive Code1*)le"); AssertEqual(TokenType.InactiveCode, GetTokenTypeAtCursor(file))
+        MoveCursorToEndOfMarker(file, "Inactive Code2*)le"); AssertEqual(TokenType.InactiveCode, GetTokenTypeAtCursor(file))
+        MoveCursorToEndOfMarker(file, "Inactive Code3*)le"); AssertEqual(TokenType.InactiveCode, GetTokenTypeAtCursor(file))
+        MoveCursorToEndOfMarker(file, "Inactive Code4*)le"); AssertEqual(TokenType.InactiveCode, GetTokenTypeAtCursor(file))
+        MoveCursorToEndOfMarker(file, "Inactive Code5*)le"); AssertEqual(TokenType.InactiveCode, GetTokenTypeAtCursor(file))
+        MoveCursorToEndOfMarker(file, "Inactive Code6*)le"); AssertEqual(TokenType.InactiveCode, GetTokenTypeAtCursor(file))
+        MoveCursorToEndOfMarker(file, "Inactive Code7*)le"); AssertEqual(TokenType.InactiveCode, GetTokenTypeAtCursor(file))
+
+
+
+        //ColorizerTest start
+    [<Test>]
+    [<Category("PerfCheck")>]
+    member public this.``Regression.Bug2986``() =
+        let code = 
+                                    [
+                                        "#light"
+                                        "let x = 12"
+                                        "(*"
+                                        "blaa"
+                                        "blaa"
+                                        "blaa"
+                                        "blaa"
+                                        "blaa"
+                                        "blaa"
+                                        "blaa"
+                                        "*)"
+                                        "open System"
+                                        "open System.IO"
+                                        "open System.Text"
+                                        "open System.Security.Cryptography"
+                                        "let fold = List.fold"
+                                        "let linkMap f xs = List.concat (List.map f xs)"
+                                        "let argv = System.Environment.GetCommandLineArgs()"
+                                        "let buildConfiguration = argv.[argv.Length - 1]"
+                                    ]
+        let (_solution, _project, file) = this.CreateSingleFileProject(code)
+        
+        // Make sure things are colored right to start
+        MoveCursorToEndOfMarker(file,"open Sys")
+        AssertEqual(TokenType.Identifier,GetTokenTypeAtCursor(file))   
+        MoveCursorToEndOfMarker(file,"open System.Security.Crypto")
+        AssertEqual(TokenType.Identifier,GetTokenTypeAtCursor(file))   
+    
+        // Delete the chunk of comments.        
+        ReplaceFileInMemory file
+                                    [
+                                        "#light"
+                                        "let x = 12"
+                                        "open System"
+                                        "open System.IO"
+                                        "open System.Text"
+                                        "open System.Security.Cryptography"
+                                        "let fold = List.fold"
+                                        "let linkMap f xs = List.concat (List.map f xs)"
+                                        "let argv = System.Environment.GetCommandLineArgs()"
+                                        "let buildConfiguration = argv.[argv.Length - 1]"
+                                    ]
+
+        // Reconfirm
+        MoveCursorToEndOfMarker(file,"open Sys")
+        AssertEqual(TokenType.Identifier,GetTokenTypeAtCursor(file))   
+        MoveCursorToEndOfMarker(file,"open System.Security.Crypto")
+        AssertEqual(TokenType.Identifier,GetTokenTypeAtCursor(file))   
+
+    [<Test>]
+    member public this.``Colorizer.AtString``() =
+        let (_solution, _project, file) = this.CreateSingleFileProject("let s = @\"Bob\"")        
+        // Check Bob
+        MoveCursorToEndOfMarker(file,"let s = @\"B")
+        AssertEqual(TokenType.String,GetTokenTypeAtCursor(file))   
+        
+    [<Test>]
+    member public this.``Regression.Bug4860``() =        
+        let fileContents = "
+let x = __SOURCE_DIRECTORY__(*Test1*)
+let y = __SOURCE_FILE__(*Test2*)
+let z = __LINE__(*Test3*)
+"
+
+        let (solution, project, file) = this.CreateSingleFileProject(fileContents)
+        
+        MoveCursorToStartOfMarker(file, "__(*Test1*)")
+        AssertEqual(TokenType.Keyword, GetTokenTypeAtCursor(file))
+        
+        MoveCursorToStartOfMarker(file, "__(*Test2*)")
+        AssertEqual(TokenType.Keyword, GetTokenTypeAtCursor(file))
+        
+        MoveCursorToStartOfMarker(file, "__(*Test3*)")
+        AssertEqual(TokenType.Keyword, GetTokenTypeAtCursor(file))        
+
+    [<Test>]
+    member public this.``Number.Regression.Bug3566``() =
+        let otherNumbers = "let other = 0x4, 0b0100, 4L, 4UL, 4u, 4s, 4us, 4y, 4uy, 4.0, 4.0f, 4N, 4I, 1M, 123"
+        let code = 
+            [ "let n = 123";
+                "let l = [12..15]";
+                "let l2 = [12 .. 15]";
+                "let l3 = [ 12 .. 15 ]";
+                "// comment1: 1234";
+                "(* comment2: 1234 *)";
+                otherNumbers;
+            ]
+        let (_solution, _project, file) = this.CreateSingleFileProject(code)
+        
+        // Check integer number
+        MoveCursorToEndOfMarker(file,"let n = 1")
+        AssertEqual(TokenType.Number,GetTokenTypeAtCursor(file))   
+
+        // Check numbers in a range expression
+        MoveCursorToEndOfMarker(file,"let l = [1")
+        AssertEqual(TokenType.Number,GetTokenTypeAtCursor(file))   
+        MoveCursorToEndOfMarker(file,"let l = [12..1")
+        AssertEqual(TokenType.Number,GetTokenTypeAtCursor(file))   
+
+        MoveCursorToEndOfMarker(file,"let l2 = [1")
+        AssertEqual(TokenType.Number,GetTokenTypeAtCursor(file))   
+        MoveCursorToEndOfMarker(file,"let l2 = [12 .. 1")
+        AssertEqual(TokenType.Number,GetTokenTypeAtCursor(file))   
+
+        MoveCursorToEndOfMarker(file,"let l3 = [ 1")
+        AssertEqual(TokenType.Number,GetTokenTypeAtCursor(file))   
+        MoveCursorToEndOfMarker(file,"let l3 = [ 12 .. 1")
+        AssertEqual(TokenType.Number,GetTokenTypeAtCursor(file))   
+        
+        // Check other numeric formats
+        let mutable index = otherNumbers.IndexOf(",")
+        while(index <> -1) do
+            let substr = otherNumbers.Substring(0, index - 1) // -1 to move into the number
+            MoveCursorToEndOfMarker(file, substr)
+            AssertEqual(TokenType.Number, GetTokenTypeAtCursor(file))   
+            index <- otherNumbers.IndexOf(",", index + 1)
+            
+        // Check that numbers in comments are not colored as numbers
+        MoveCursorToEndOfMarker(file,"// comment1: 12")
+        AssertEqual(TokenType.Comment,GetTokenTypeAtCursor(file))   
+
+        MoveCursorToEndOfMarker(file,"(* comment2: 12")
+        AssertEqual(TokenType.Comment,GetTokenTypeAtCursor(file))   
+            
+       
+    /// FEATURE: Hash commands in .fsx files are colorized in PreprocessorKeyword color        
+    [<Test>]
+    member public this.``Preprocessor.InFsxFile``() =
+        let code = 
+            [
+                "#reference @\"\""
+                "#load @\"\""
+                "#I <--hash I"
+                "#time @\"\""
+                "    #reference @\"\""
+                "    #load @\"\""
+                "    #I <--spaces then hash I"
+                "    #time @\"\""                                     
+            ]
+        let (_, _, file) = this.CreateSingleFileProject(code, fileKind = SourceFileKind.FSX)
+        
+        MoveCursorToEndOfMarker(file,"#ref")
+        AssertEqual(TokenType.PreprocessorKeyword ,GetTokenTypeAtCursor(file))                           
+        MoveCursorToEndOfMarker(file,"#loa")
+        AssertEqual(TokenType.PreprocessorKeyword ,GetTokenTypeAtCursor(file))                           
+        MoveCursorToStartOfMarker(file,"I <--hash I")
+        AssertEqual(TokenType.PreprocessorKeyword ,GetTokenTypeAtCursor(file))                           
+        MoveCursorToEndOfMarker(file,"#ti")
+        AssertEqual(TokenType.PreprocessorKeyword ,GetTokenTypeAtCursor(file))  
+        MoveCursorToEndOfMarker(file,"    #ref")
+        AssertEqual(TokenType.PreprocessorKeyword ,GetTokenTypeAtCursor(file))                           
+        MoveCursorToEndOfMarker(file,"    #loa")
+        AssertEqual(TokenType.PreprocessorKeyword ,GetTokenTypeAtCursor(file))                           
+        MoveCursorToStartOfMarker(file,"I <--spaces then hash I")
+        AssertEqual(TokenType.PreprocessorKeyword ,GetTokenTypeAtCursor(file))                           
+        MoveCursorToEndOfMarker(file,"    #ti")
+        AssertEqual(TokenType.PreprocessorKeyword ,GetTokenTypeAtCursor(file))     
+                             
+        
+    /// FEATURE: Script-specific hash commands do not show up in blue in .fs files.
+    [<Test>]
+    member public this.``Preprocessor.InFsFile``() =
+        let code = 
+            [
+                "#reference @\"\""
+                "#load @\"\""
+                "#I <--hash I"
+                "#time @\"\""
+                "    #reference @\"\""
+                "    #load @\"\""
+                "    #I <--spaces then hash I"
+                "    #time @\"\""                                     
+            ]
+        let (_, _, file) = this.CreateSingleFileProject(code)
+        
+        MoveCursorToEndOfMarker(file,"#ref")
+        AssertEqual(TokenType.Text,GetTokenTypeAtCursor(file))                           
+        MoveCursorToEndOfMarker(file,"#loa")
+        AssertEqual(TokenType.Text ,GetTokenTypeAtCursor(file))                           
+        MoveCursorToStartOfMarker(file,"I <--hash I")
+        AssertEqual(TokenType.Text ,GetTokenTypeAtCursor(file))                           
+        MoveCursorToEndOfMarker(file,"#ti")
+        AssertEqual(TokenType.Text ,GetTokenTypeAtCursor(file))  
+        MoveCursorToEndOfMarker(file,"    #ref")
+        AssertEqual(TokenType.Text ,GetTokenTypeAtCursor(file))                           
+        MoveCursorToEndOfMarker(file,"    #loa")
+        AssertEqual(TokenType.Text ,GetTokenTypeAtCursor(file))                           
+        MoveCursorToStartOfMarker(file,"I <--spaces then hash I")
+        AssertEqual(TokenType.Text ,GetTokenTypeAtCursor(file))                           
+        MoveCursorToEndOfMarker(file,"    #ti")
+        AssertEqual(TokenType.Text ,GetTokenTypeAtCursor(file))                                    
+
+    /// FEATURE: Nested (* *) comments are allowed and will be colorized with CommentColor. Only the final *) causes the comment to close.
+    [<Test>]
+    member public this.``Comment.AfterCommentBlock``() =
+        let code = 
+            ["(*Bob*)type Bob() = class end"
+             "(*"
+             "(*"
+             "(*Alice*)type Alice() = class end"
+             "*)"
+             "*)"
+             "(*Charles*)type Charles() = class end"]
+        let (_, _, file) = this.CreateSingleFileProject(code)
+        // Check Bob
+        MoveCursorToEndOfMarker(file,"(*Bob*)t")
+        AssertEqual(TokenType.Keyword,GetTokenTypeAtCursor(file))
+        
+        // Check Alice
+        MoveCursorToEndOfMarker(file,"(*Alice*)t")
+        AssertEqual(TokenType.Comment,GetTokenTypeAtCursor(file))
+        
+        // Check Charles
+        MoveCursorToEndOfMarker(file,"(*Charles*)t")
+        AssertEqual(TokenType.Keyword,GetTokenTypeAtCursor(file))
+        
+    /// BUG: The comment used to be colored in black.
+    [<Test>]
+    member public this.``Regression.Bug1596``() =
+        let code = [" let 2d (* Identifiers cannot start with numbers *)"]
+        let (_, _, file) = this.CreateSingleFileProject(code)
+        
+        // Check Bob
+        MoveCursorToEndOfMarker(file,"let 2d (* Ide")
+        AssertEqual(TokenType.Comment,GetTokenTypeAtCursor(file))
+  
+        
+    /// FEATURE: Code inside #if\#else\#endif blocks is colored with InactiveCodeColor depending on defines. This works for nested #if blocks as well.
+    [<Test>]
+    member public this.``Preprocessor.AfterPreprocessorBlock``() =
+        let code = 
+               ["(*Bob*)type Bob() = class end"
+                "#if UNDEFINED"
+                "    #if UNDEFINED"
+                "    (*Alice*)type Alice() = class end"
+                "    #else"
+                "    (*Tom*)type Tom() = class end"
+                "    #endif"
+                "#else"
+                "    #if UNDEFINED"
+                "    (*Maurice*)type Maurice() = class end"
+                "    #else"
+                "    (*Larry*)type Larry() = class end"
+                "    #endif"
+                "#endif"
+                "(*Charles*)type Charles() = class end"]
+        let (_, _, file) = this.CreateSingleFileProject(code)
+        
+        let check marker token = 
+            MoveCursorToEndOfMarker(file,marker)
+            AssertEqual(token,GetTokenTypeAtCursor(file))
+        
+        check "(*Bob*)t" TokenType.Keyword 
+        check "(*Alice*)t" TokenType.InactiveCode
+        check "(*Tom*)t" TokenType.InactiveCode 
+        check "(*Maurice*)t" TokenType.InactiveCode 
+        check "(*Larry*)t" TokenType.Keyword 
+        check "(*Charles*)t" TokenType.Keyword 
+
+    // Wrong "#else" in "#if" should be ignored
+    [<Test>]
+    member public this.``Preprocessor.InvalidElseDirectiveIgnored``() =
+        let code = 
+                                    ["#if UNDEFINED"
+                                     "    (*Alice*)type Alice() = class end"
+                                     "(**) #else"
+                                     "    (*Larry*)type Larry() = class end"
+                                     "#endif"]
+        let (_, _, file) = this.CreateSingleFileProject(code)
+        let check marker token = 
+            MoveCursorToEndOfMarker(file,marker)
+            AssertEqual(token,GetTokenTypeAtCursor(file))
+        
+        check "(*Alice*)t" TokenType.InactiveCode
+        check "(*Larry*)t" TokenType.InactiveCode
+        
+    /// FEATURE: Code inside #if\#else\#endif blocks is colored with InactiveCodeColor depending on defines. This works for nested #if blocks as well.
+    [<Test>]
+    member public this.``Preprocessor.AfterPreprocessorBlockWithDefines``() =
+        let code = 
+                                    ["(*Bob*)type Bob() = class end"
+                                     "#if UNDEFINED"
+                                     "    #if UNDEFINED"
+                                     "    (*Alice*)type Alice() = class end"
+                                     "    #else"
+                                     "    (*Tom*)type Tom() = class end"
+                                     "    #endif"
+                                     "#else"
+                                     "    #if UNDEFINED"
+                                     "    (*Maurice*)type Maurice() = class end"
+                                     "    #else"
+                                     "    (*Larry*)type Larry() = class end"
+                                     "    #endif"
+                                     "#endif"
+                                     "(*Charles*)type Charles() = class end"]
+        let (_, _, file) = this.CreateSingleFileProject(code, defines = ["FOO";"UNDEFINED"])
+        
+        let check marker token = 
+            MoveCursorToEndOfMarker(file,marker)
+            AssertEqual(token,GetTokenTypeAtCursor(file))
+
+        check "(*Bob*)t" TokenType.Keyword 
+        check "(*Alice*)t" TokenType.Keyword
+        check "(*Tom*)t" TokenType.InactiveCode 
+        check "(*Maurice*)t" TokenType.InactiveCode 
+        check "(*Larry*)t" TokenType.InactiveCode
+        check "(*Charles*)t" TokenType.Keyword 
+        
+    /// FEATURE: Preprocessor keywords #light\#if\#else\#endif are colored with the PreprocessorKeyword color.
+    /// FEATURE: All code in the inactive side of #if\#else\#endif is colored with with InactiveCode color.
+    [<Test>]
+    member public this.``Preprocessor.Keywords``() =
+        let code = 
+                                    ["#light (*Light*)"
+                                     "  #if UNDEFINED //(*If*)"
+                                     "    let x = 1(*Inactive*)"
+                                     "  #else //(*Else*)"
+                                     "    let(*Active*) x = 1"
+                                     "  #endif //(*Endif*)"]
+        let (_, _, file) = this.CreateSingleFileProject(code)
+        
+        let check marker token = 
+            MoveCursorToStartOfMarker(file,marker)
+            AssertEqual(token,GetTokenTypeAtCursor(file))
+        
+        check "light (*Light*)" TokenType.PreprocessorKeyword
+        check "(*Inactive*)" TokenType.InactiveCode
+        check "if UNDEFINED //(*If*)" TokenType.PreprocessorKeyword
+        check "FINED //(*If*)" TokenType.Identifier
+        check "(*If*)" TokenType.Comment
+        check "else //(*Else*)" TokenType.PreprocessorKeyword
+        check "t(*Active*)" TokenType.Keyword
+        check "endif //(*Endif*)" TokenType.PreprocessorKeyword
+        check "(*If*)" TokenType.Comment
+        check "(*Else*)" TokenType.Comment
+        check "(*Endif*)" TokenType.Comment
+        
+    /// #else / #endif in multiline strings is ignored
+    [<Test>]
+    member public this.``Preprocessor.DirectivesInString``() =
+        let code = 
+                                    ["#light"
+                                     ""
+                                     "#if DEFINED"
+                                     "let s = \""
+                                     "#else"
+                                     "\""
+                                     "let testme = 1"
+                                     "#endif"]
+        let (_, _, file) = this.CreateSingleFileProject(code, defines = ["DEFINED"])
+        MoveCursorToStartOfMarker(file,"let testme")
+        AssertEqual(TokenType.Keyword,GetTokenTypeAtCursor(file))
+        
+    /// Bug 2076 - String literals were causing the endif stack information to be discarded
+    [<Test>]
+    member public this.``Preprocessor.KeywordsWithStrings``() =
+        let code = 
+                                    ["#light (*Light*)"
+                                     "let x1 = \"string1\""
+                                     "#if UNDEFINED //(*If*)"
+                                     "let x2 = \"string2\""
+                                     "#else //(*Else*)"
+                                     "let x3 = \"string3\""
+                                     "#endif //(*Endif*)"
+                                     "let x4 = \"string4\""]
+        let (_, _, file) = this.CreateSingleFileProject(code)
+        
+        let check marker token = 
+            MoveCursorToStartOfMarker(file,marker)
+            AssertEqual(token,GetTokenTypeAtCursor(file))
+        check "if UNDEFINED //(*If*)" TokenType.PreprocessorKeyword
+        check "else //(*Else*)" TokenType.PreprocessorKeyword
+        check "endif //(*Endif*)" TokenType.PreprocessorKeyword
+
+    [<Test>]
+    member public this.``Comment.VerbatimStringInComment.Bug1778``() =
+        let code = 
+                                    ["#light"
+                                     "(* @\"\\\" *) let a = 0"]
+        let (_, _, file) = this.CreateSingleFileProject(code)
+      
+        MoveCursorToStartOfMarker(file, "le")
+        AssertEqual(TokenType.Keyword ,GetTokenTypeAtCursor(file))
+
+    [<Test>]
+    member public this.``Preprocessor.KeywordsWrongIf.Bug1577``() =
+        let code = 
+                                    ["#if !!!!!!!!!!!!!!!COMPILED"
+                                     "#endif"]
+        let (_, _, file) = this.CreateSingleFileProject(code)
+        MoveCursorToStartOfMarker(file, "!!COMPILED")
+        AssertEqual(TokenType.Operator, GetTokenTypeAtCursor(file))
+
+
+    // This was an off-by-one bug in the replacement Colorizer
+    [<Test>]
+    member public this.``Keyword.LastCharacterOfKeyword``() =
+        let code = ["(*Bob*)type Bob() = int"]
+        let (_, _, file) = this.CreateSingleFileProject(code)
+        
+        // Check Bob
+        MoveCursorToEndOfMarker(file,"(*Bob*)typ")
+        AssertEqual(TokenType.Keyword,GetTokenTypeAtCursor(file))
+
+
+// Allow languageService tests to run under different contextes
+namespace UnitTests.Tests.LanguageService.Colorizer
+open UnitTests.Tests.LanguageService
+open UnitTests.TestLib.LanguageService
+open UnitTests.TestLib.ProjectSystem
+open NUnit.Framework
+open Salsa.Salsa
+
+// context msbuild
+[<TestFixture>]
+[<Category("LanguageService.MSBuild")>]
+type ``MSBuild`` = 
+   inherit ColorizerTests
+   new() = { inherit ColorizerTests(VsOpts = fst (Models.MSBuild())); }
+
+// Context project system
+[<TestFixture>]
+[<Category("LanguageService.ProjectSystem")>]
+type ``ProjectSystem`` = 
+    inherit ColorizerTests
+    new() = { inherit ColorizerTests(VsOpts = LanguageServiceExtension.ProjectSystem); }  
\ No newline at end of file
diff --git a/vsintegration/src/unittests/Tests.LanguageService.Completion.fs b/vsintegration/src/unittests/Tests.LanguageService.Completion.fs
new file mode 100644
index 0000000..0c2504e
--- /dev/null
+++ b/vsintegration/src/unittests/Tests.LanguageService.Completion.fs
@@ -0,0 +1,7610 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+namespace UnitTests.Tests.LanguageService
+
+open System
+open Salsa.VsMocks
+open Salsa.VsOpsUtils
+open NUnit.Framework
+open UnitTests.TestLib.Salsa
+open UnitTests.TestLib.Utils
+open Salsa.Salsa
+
+open UnitTests.TestLib.LanguageService
+
+[<AutoOpen>]
+module StandardSettings = 
+    let standard40AssemblyRefs  = [ "System"; "System.Core"; "System.Numerics" ]
+    let queryAssemblyRefs = [ "System.Xml.Linq"; "System.Core" ]
+    type Expectation = 
+        | QuickInfoExpected of string * string
+        | AutoCompleteExpected of string * string
+        | DotCompleteExpected of string * string
+    let QI x y = QuickInfoExpected(x,y)
+    let AC x y = AutoCompleteExpected(x,y)
+    let DC x y = DotCompleteExpected(x,y)
+
+type AutoCompletionListTests() as this  = 
+    inherit LanguageServiceBaseTests()
+
+    let createFile (code : list<string>) fileKind refs = 
+        let (_, _, file) = 
+            match code with
+            | [code] when code.IndexOfAny([|'\r'; '\n'|]) <> -1 ->
+                this.CreateSingleFileProject(code, fileKind = fileKind, references = refs)
+            | code -> this.CreateSingleFileProject(code, fileKind = fileKind, references = refs)
+        file
+
+    let DoWithAutoCompleteUsingExtraRefs refs coffeeBreak fileKind reason (code : list<string>) marker f  =        
+        // Up to 2 untyped parse operations are OK: we do an initial parse to provide breakpoint valdiation etc. 
+        // This might be before the before the background builder is ready to process the foreground typecheck.
+        // In this case the background builder calls us back when its ready, and we then request a foreground typecheck 
+        let file = createFile code fileKind refs
+            
+        if coffeeBreak then
+            TakeCoffeeBreak(this.VS)
+        let gpatcc = GlobalParseAndTypeCheckCounter.StartNew(this.VS)
+        MoveCursorToEndOfMarker(file, marker)
+        let completions = CompleteAtCursorForReason(file,reason)
+        f completions
+        gpatcc.AssertExactly(0,0)
+
+
+    let DoWithAutoComplete coffeeBreak fileKind reason (code : list<string>) marker f  = DoWithAutoCompleteUsingExtraRefs [] coffeeBreak fileKind reason code marker f
+
+    let AssertAutoCompleteContains, AssertAutoCompleteContainsNoCoffeeBreak, AutoCompleteInInterfaceFileContains, AssertCtrlSpaceCompleteContains, AssertCtrlSpaceCompleteContainsNoCoffeeBreak = 
+        let AssertAutoCompleteContains coffeeBreak filename reason code marker  should shouldnot  =        
+            DoWithAutoComplete coffeeBreak filename reason code marker <| 
+                fun completions ->
+                AssertCompListContainsAll(completions, should)
+                AssertCompListDoesNotContainAny(completions, shouldnot) 
+
+        ((AssertAutoCompleteContains true SourceFileKind.FS Microsoft.VisualStudio.FSharp.LanguageService.BackgroundRequestReason.MemberSelect),
+         (AssertAutoCompleteContains false SourceFileKind.FS Microsoft.VisualStudio.FSharp.LanguageService.BackgroundRequestReason.MemberSelect),
+         (AssertAutoCompleteContains true SourceFileKind.FSI Microsoft.VisualStudio.FSharp.LanguageService.BackgroundRequestReason.MemberSelect),
+         (AssertAutoCompleteContains true SourceFileKind.FS Microsoft.VisualStudio.FSharp.LanguageService.BackgroundRequestReason.CompleteWord),
+         (AssertAutoCompleteContains false SourceFileKind.FS Microsoft.VisualStudio.FSharp.LanguageService.BackgroundRequestReason.CompleteWord))
+    
+    let AssertCtrlSpaceCompletionListIsEmpty code marker = 
+        DoWithAutoComplete true SourceFileKind.FS Microsoft.VisualStudio.FSharp.LanguageService.BackgroundRequestReason.CompleteWord code marker AssertCompListIsEmpty
+
+    let AssertCtrlSpaceCompletionListIsEmptyNoCoffeeBreak code marker = 
+        DoWithAutoComplete false SourceFileKind.FS Microsoft.VisualStudio.FSharp.LanguageService.BackgroundRequestReason.CompleteWord code marker AssertCompListIsEmpty
+
+    let AssertAutoCompleteCompletionListIsEmpty code marker = 
+        DoWithAutoComplete true SourceFileKind.FS Microsoft.VisualStudio.FSharp.LanguageService.BackgroundRequestReason.MemberSelect code marker AssertCompListIsEmpty
+
+    let AssertAutoCompleteCompletionListIsEmptyNoCoffeeBreak code marker = 
+        DoWithAutoComplete false SourceFileKind.FS Microsoft.VisualStudio.FSharp.LanguageService.BackgroundRequestReason.MemberSelect code marker AssertCompListIsEmpty
+
+
+    let testAutoCompleteAdjacentToDot op =
+        let text = sprintf "System.Console%s" op
+
+        // First, test that pressing dot works.
+        AssertAutoCompleteContainsNoCoffeeBreak 
+          [ text ]
+          "System.Console."
+          [ "BackgroundColor" ] // should contain
+          [ ] // should not contain
+ 
+    let testAutoCompleteAdjacentToDotNegative op =
+        let text = sprintf "System.Console%s" op
+
+        // Next test that there is no completion after then end.
+        AssertCtrlSpaceCompleteContainsNoCoffeeBreak 
+          [ text ]
+          text
+          [ "abs" ] // should contain (top-level autocomplete on empty identifier)
+          [ "BackgroundColor" ] // should not contain (from prior System.Console)
+
+    let customOperations = 
+      [ "contains"; "count";"last"; "lastOrDefault"; "exactlyOne"; "exactlyOneOrDefault"; "headOrDefault"; "select"; "where"
+        "minBy"; "maxBy"; "groupBy"; "sortBy"; "sortByDescending"; "thenBy"; "thenByDescending"; "groupValBy"; "join"
+        "groupJoin"; "sumByNullable"; "minByNullable"; "maxByNullable"; "averageByNullable"; "averageBy"
+        "distinct"; "exists"; "find"; "all"; "head"; "nth"; "skip"; "skipWhile"; "sumBy"; "take"
+        "takeWhile"; "sortByNullable"; "sortByNullableDescending"; "thenByNullable"; "thenByNullableDescending"]
+
+#if FX_ATLEAST_45
+    let AA l = Some(System.IO.Path.Combine(System.IO.Path.GetTempPath(), ".NETFramework,Version=v4.0.AssemblyAttributes.fs")), l
+    let notAA l = None,l
+#else
+    let AA l = None, l
+    let notAA l = None,l
+#endif
+    let stopWatch = new System.Diagnostics.Stopwatch()
+    let ResetStopWatch() = stopWatch.Reset(); stopWatch.Start()
+    let time1 op a message = 
+        ResetStopWatch()
+        let result = op a
+        //printf "%s %d ms\n" message stopWatch.ElapsedMilliseconds
+        result
+
+    let ShowErrors(project:OpenProject) =     
+        for error in (GetErrors(project)) do
+            printf "%s\n" (error.ToString())    
+
+
+    // There are some dot completion tests in this type as well, in the systematic tests for queries
+    member private this.VerifyDotCompListContainAllAtStartOfMarker(fileContents : string, marker : string, list :string list, ?addtlRefAssy:list<string>, ?coffeeBreak:bool) =
+        let (solution, project, file) = this.CreateSingleFileProject(fileContents, ?references = addtlRefAssy)
+
+        //to add references
+        if defaultArg coffeeBreak false then TakeCoffeeBreak(this.VS)
+        let completions = DotCompletionAtStartOfMarker file marker
+        AssertCompListContainsAll(completions, list)
+
+    // There are some quickinfo tests in this file as well, in the systematic tests for queries
+    member public this.InfoInDeclarationTestQuickInfoImpl(code : string,marker,expected,atStart, ?addtlRefAssy : list<string>) =
+        let (solution, project, file) = this.CreateSingleFileProject(code, ?references = addtlRefAssy)
+
+        let gpatcc = GlobalParseAndTypeCheckCounter.StartNew(this.VS)
+        if atStart then
+            MoveCursorToStartOfMarker(file, marker)
+        else
+            MoveCursorToEndOfMarker(file, marker)
+
+        let tooltip = time1 GetQuickInfoAtCursor file "Time of first tooltip"
+        AssertContains(tooltip, expected) 
+        gpatcc.AssertExactly(0,0)
+
+    member public this.AssertQuickInfoContainsAtEndOfMarker(code,marker,expected, ?addtlRefAssy : list<string>) =
+        this.InfoInDeclarationTestQuickInfoImpl(code,marker,expected,false,?addtlRefAssy=addtlRefAssy)
+    static member charExpectedCompletions = [
+        "CompareTo"; // Members defined on System.Char
+        "GetHashCode"] // Members defined on System.Object
+
+    static member intExpectedCompletions = [
+        "CompareTo"; // Members defined on System.Int32
+        "GetHashCode"] // Members defined on System.Object
+    
+    static member stringExpectedCompletions = [
+        "Substring"; // Methods of System.String
+        "GetHashCode"] // Methods of System.Object
+
+    static member arrayExpectedCompletions = [
+        "Length"; ] // Methods of System.Object
+
+    member private this.AutoCompleteBug70080HelperHelper(programText:string, shouldContain, shouldNotContain) =
+        let i = programText.IndexOf("[<Attr ")
+        if i = -1 then failwith "Could not find expected '[<Attr ' in program"
+        AssertCtrlSpaceCompleteContains
+          [ programText ]
+          "[<Attr"       // marker
+          shouldContain
+          shouldNotContain
+        let s = programText.Insert(i+2, "type:")
+        AssertCtrlSpaceCompleteContains 
+          [ s ]
+          "[<type:Attr"       // marker
+          shouldContain // should contain
+          shouldNotContain
+        let s = programText.Insert(i+2, "module:")
+        AssertCtrlSpaceCompleteContains 
+          [ s ]
+          "[<module:Attr"       // marker
+          shouldContain // should contain
+          shouldNotContain
+
+    member public this.AutoCompleteBug70080Helper(programText:string) =
+        this.AutoCompleteBug70080HelperHelper(programText, ["AttributeUsageAttribute"], [])
+
+    member private this.testAutoCompleteAdjacentToDot op =
+        let text = sprintf "System.Console%s" op
+        // First, test that pressing dot works.
+        AssertAutoCompleteContainsNoCoffeeBreak 
+          [ text ]
+          "System.Console."
+          [ "BackgroundColor" ] // should contain
+          [ ] // should not contain   
+
+    //**Help Function for checking Ctrl-Space Completion Contains the expected value *************
+    member private this.AssertCtrlSpaceCompletionContains(fileContents : list<string>, marker, expected, ?addtlRefAssy: list<string>)  = 
+        let (_, _, file) = this.CreateSingleFileProject(fileContents, ?references = addtlRefAssy)
+        MoveCursorToEndOfMarker(file,marker)
+        let completions = CtrlSpaceCompleteAtCursor file
+        Assert.AreNotEqual(0,completions.Length)
+        let found = completions |> Array.exists(fun (s,_,_,_) -> s = expected)
+        if not(found) then 
+            printfn "Expected: %A to contain %s" completions expected  
+            Assert.Fail() 
+
+    member private this.AutoCompletionListNotEmpty (fileContents : list<string>) marker  = 
+        let (_, _, file) = this.CreateSingleFileProject(fileContents)
+        MoveCursorToEndOfMarker(file,marker)
+        let completions = AutoCompleteAtCursor file
+        Assert.AreNotEqual(0,completions.Length)
+
+    member public this.TestCompletionNotShowingWhenFastUpdate (firstSrc : list<string>) secondSrc marker =     
+        let (_, _, file) = this.CreateSingleFileProject(firstSrc)
+        MoveCursorToEndOfMarker(file,marker)
+        
+        // Now delete the property and leave only dot at the end 
+        //  - user is typing fast so replac the content without background compilation
+        ReplaceFileInMemoryWithoutCoffeeBreak file secondSrc      
+        let completions = time1 AutoCompleteAtCursor file "Time of first autocomplete."
+        AssertCompListIsEmpty(completions)
+
+        // Recheck after some time - after the background compilation runs
+        TakeCoffeeBreak(this.VS)                                      
+        let completions = time1 AutoCompleteAtCursor file "Time of first autocomplete."
+        AssertCompListIsEmpty(completions)      
+
+    [<Test>]
+    member this.``AutoCompletion.ObjectMethods``() = 
+        let code =
+            [
+                "type DU1 = DU_1"
+                
+                "[<NoEquality>]"
+                "type DU2 = DU_2"
+
+                "[<NoEquality>]"
+                "type DU3 ="
+                "   | DU_3"
+                "   with member this.Equals(b : string) = 1"
+
+                "[<NoEquality>]"
+                "type DU4 ="
+                "   | DU_4"
+                "   with member this.GetHashCode(b : string) = 1"
+
+
+                "module Extensions ="
+                "    type System.Object with"
+                "       member this.ExtensionPropObj = 42"
+                "       member this.ExtensionMethodObj () = 42"
+ 
+                "open Extensions"
+            ]
+        let (_, _, file) = this.CreateSingleFileProject(code)
+        let test tail marker expected notExpected =
+            let code = code @ [tail]
+            ReplaceFileInMemory file code
+            MoveCursorToEndOfMarker(file,marker)
+
+            let completions = AutoCompleteAtCursor file
+            AssertCompListContainsAll(completions, expected)
+            AssertCompListDoesNotContainAny(completions, notExpected)
+
+        test "obj()." ")." ["Equals"; "ExtensionPropObj"; "ExtensionMethodObj"] []
+        test  "System.Object." "Object." ["Equals"; "ReferenceEquals"] []
+        test "System.String." "String." ["Equals"] []
+        test "DU_1." "DU_1." ["Equals"; "GetHashCode"; "ExtensionMethodObj"; "ExtensionPropObj"] []
+        test "DU_2." "DU_2." ["ExtensionPropObj"; "ExtensionMethodObj"] ["Equals"; "GetHashCode"] // no equals\gethashcode
+        test "DU_3." "DU_3." ["ExtensionPropObj"; "ExtensionMethodObj"; "Equals"] ["GetHashCode"] // no gethashcode, has equals defined in DU3 type
+        test "DU_4." "DU_4." ["ExtensionPropObj"; "ExtensionMethodObj"; "GetHashCode"] ["Equals"] // no equals, has gethashcode defined in DU4 type
+
+    
+    [<Test>]
+    member this.``AutoCompletion.BeforeThis``() = 
+        let code = 
+            [
+                [
+                "type A() ="
+                "   member __.X = ()"
+                "   member this."
+                ]
+                [
+                "type A() ="
+                "   member __.X = ()"
+                "   member private this."
+                ]
+                [
+                "type A() ="
+                "   member __.X = ()"
+                "   member public this."
+                ]
+                [
+                "type A() ="
+                "   member __.X = ()"
+                "   member internal this."
+                ]
+
+            ]
+
+        for c in code do
+            AssertCtrlSpaceCompletionListIsEmpty c "this."
+            AssertAutoCompleteCompletionListIsEmpty c "this."
+            AssertCtrlSpaceCompletionListIsEmptyNoCoffeeBreak c "this."
+            AssertAutoCompleteCompletionListIsEmptyNoCoffeeBreak c "this."
+                    
+    [<Test>]
+    [<Category("TypeProvider")>]
+    member this.``TypeProvider.VisibilityChecksForGeneratedTypes``() = 
+        let extraRefs = [System.IO.Path.Combine(System.Environment.CurrentDirectory, @"UnitTestsResources\MockTypeProviders\DummyProviderForLanguageServiceTesting.dll")]
+        let check = DoWithAutoCompleteUsingExtraRefs extraRefs true SourceFileKind.FS Microsoft.VisualStudio.FSharp.LanguageService.BackgroundRequestReason.MemberSelect
+
+        let code = 
+            [
+                "type T = GeneratedType.SampleType"
+
+                "let t = T(5)"
+                "t."
+
+                "T."
+
+
+                "type T1() = "
+                "    inherit T(5)"
+                "    member this.Foo() = this."
+            ]
+        check code "T." <| 
+            fun ci -> 
+                AssertCompListContains(ci, "PublicField")
+
+        check code "t." <|
+            fun ci ->
+                AssertCompListContainsAll(ci, ["PublicM"; "PublicProp"])
+                AssertCompListDoesNotContainAny(ci, ["f"; "ProtectedProp"; "PrivateProp"; "ProtectedM"; "PrivateM"])
+
+        check code "= this." <|
+            fun ci ->
+                AssertCompListContainsAll(ci, ["PublicM"; "PublicProp"; "ProtectedProp"; "ProtectedM"])
+                AssertCompListDoesNotContainAny(ci, ["f"; "PrivateProp"; "PrivateM"])
+                
+               
+    [<Test>] member public this.``AdjacentToDot_01``() = testAutoCompleteAdjacentToDot ".."
+    [<Test>] member public this.``AdjacentToDot_02``() = testAutoCompleteAdjacentToDot ".<"
+    [<Test>] member public this.``AdjacentToDot_03``() = testAutoCompleteAdjacentToDot ".>"
+    [<Test>] member public this.``AdjacentToDot_04``() = testAutoCompleteAdjacentToDot ".="
+    [<Test>] member public this.``AdjacentToDot_05``() = testAutoCompleteAdjacentToDot ".!="
+    [<Test>] member public this.``AdjacentToDot_06``() = testAutoCompleteAdjacentToDot ".$"
+    [<Test>] member public this.``AdjacentToDot_07``() = testAutoCompleteAdjacentToDot ".[]"
+    [<Test>] member public this.``AdjacentToDot_08``() = testAutoCompleteAdjacentToDot ".[]<-"
+    [<Test>] member public this.``AdjacentToDot_09``() = testAutoCompleteAdjacentToDot ".[,]<-"
+    [<Test>] member public this.``AdjacentToDot_10``() = testAutoCompleteAdjacentToDot ".[,,]<-"
+    [<Test>] member public this.``AdjacentToDot_11``() = testAutoCompleteAdjacentToDot ".[,,,]<-"
+    [<Test>] member public this.``AdjacentToDot_12``() = testAutoCompleteAdjacentToDot ".[,,,]"
+    [<Test>] member public this.``AdjacentToDot_13``() = testAutoCompleteAdjacentToDot ".[,,]"
+    [<Test>] member public this.``AdjacentToDot_14``() = testAutoCompleteAdjacentToDot ".[,]"
+    [<Test>] member public this.``AdjacentToDot_15``() = testAutoCompleteAdjacentToDot ".[..]"
+    [<Test>] member public this.``AdjacentToDot_16``() = testAutoCompleteAdjacentToDot ".[..,..]"
+    [<Test>] member public this.``AdjacentToDot_17``() = testAutoCompleteAdjacentToDot ".[..,..,..]"
+    [<Test>] member public this.``AdjacentToDot_18``() = testAutoCompleteAdjacentToDot ".[..,..,..,..]"
+    [<Test>] member public this.``AdjacentToDot_19``() = testAutoCompleteAdjacentToDot ".()"
+    [<Test>] member public this.``AdjacentToDot_20``() = testAutoCompleteAdjacentToDot ".()<-"
+    [<Test>] member public this.``AdjacentToDot_02_Negative``() = testAutoCompleteAdjacentToDotNegative ".<"
+    [<Test>] member public this.``AdjacentToDot_03_Negative``() = testAutoCompleteAdjacentToDotNegative ".>"
+    [<Test>] member public this.``AdjacentToDot_04_Negative``() = testAutoCompleteAdjacentToDotNegative ".="
+    [<Test>] member public this.``AdjacentToDot_05_Negative``() = testAutoCompleteAdjacentToDotNegative ".!="
+    [<Test>] member public this.``AdjacentToDot_06_Negative``() = testAutoCompleteAdjacentToDotNegative ".$"
+    [<Test>] member public this.``AdjacentToDot_07_Negative``() = testAutoCompleteAdjacentToDotNegative ".[]"
+    [<Test>] member public this.``AdjacentToDot_08_Negative``() = testAutoCompleteAdjacentToDotNegative ".[]<-"
+    [<Test>] member public this.``AdjacentToDot_09_Negative``() = testAutoCompleteAdjacentToDotNegative ".[,]<-"
+    [<Test>] member public this.``AdjacentToDot_10_Negative``() = testAutoCompleteAdjacentToDotNegative ".[,,]<-"
+    [<Test>] member public this.``AdjacentToDot_11_Negative``() = testAutoCompleteAdjacentToDotNegative ".[,,,]<-"
+    [<Test>] member public this.``AdjacentToDot_12_Negative``() = testAutoCompleteAdjacentToDotNegative ".[,,,]"
+    [<Test>] member public this.``AdjacentToDot_13_Negative``() = testAutoCompleteAdjacentToDotNegative ".[,,]"
+    [<Test>] member public this.``AdjacentToDot_14_Negative``() = testAutoCompleteAdjacentToDotNegative ".[,]"
+    [<Test>] member public this.``AdjacentToDot_15_Negative``() = testAutoCompleteAdjacentToDotNegative ".[..]"
+    [<Test>] member public this.``AdjacentToDot_16_Negative``() = testAutoCompleteAdjacentToDotNegative ".[..,..]"
+    [<Test>] member public this.``AdjacentToDot_17_Negative``() = testAutoCompleteAdjacentToDotNegative ".[..,..,..]"
+    [<Test>] member public this.``AdjacentToDot_18_Negative``() = testAutoCompleteAdjacentToDotNegative ".[..,..,..,..]"
+    [<Test>] member public this.``AdjacentToDot_19_Negative``() = testAutoCompleteAdjacentToDotNegative ".()"
+    [<Test>] member public this.``AdjacentToDot_20_Negative``() = testAutoCompleteAdjacentToDotNegative ".()<-"
+    [<Test>] member public this.``AdjacentToDot_21_Negative``() = testAutoCompleteAdjacentToDotNegative ".+."
+
+    [<Test>]
+    member public this.``LambdaOverloads.Completion``() = 
+        let prologue = "open System.Linq"
+        let cases = 
+            [
+                "[\"\"].Sum(fun x -> (*$*)x.Len )"
+                "[\"\"].Select(fun x -> (*$*)x.Len )"
+                "[\"\"].Select(fun x i -> (*$*)x.Len )"
+                "[\"\"].GroupBy(fun x -> (*$*)x.Len )"
+                "[\"\"].Join([\"\"], (fun x -> (*$*)x.Len), (fun x -> x.Len), (fun x y -> x.Len+ y.Len))"
+                "[\"\"].Join([\"\"], (fun x -> x.Len), (fun x -> (*$*)x.Len), (fun x y -> x.Len+ y.Len))"
+                "[\"\"].Join([\"\"], (fun x -> x.Len), (fun x -> x.Len), (fun x y -> (*$*)x.Len + y.Len))"
+                "[\"\"].Join([\"\"], (fun x -> x.Len), (fun x -> x.Len), (fun y x -> y.Len + (*$*)x.Len))"
+                "[\"\"].Where(fun x -> (*$*)x.Len )"
+                "[\"\"].Where(fun x -> (*$*)x.Len % 3 )"
+                "[\"\"].Where(fun x -> (*$*)x.Len % 3 = 0)"
+                "[\"\"].AsQueryable().Select(fun x -> (*$*)x.Len )"
+                "[\"\"].AsQueryable().Select(fun x i -> (*$*)x.Len )"
+                "[\"\"].AsQueryable().Where(fun x -> (*$*)x.Len )"
+            ]
+            
+        for case in cases do
+            let code = [prologue; case]
+            AssertCtrlSpaceCompleteContains code "(*$*)x.Len" ["Length"] []
+
+    [<Test>]
+    member public this.``Query.CompletionInJoinOn``() = 
+        let code = 
+            [
+                "query {"
+                "   for a in [1] do"
+                "   join b in [2] on (a.)"
+                "   select (a + b)"
+                "}"
+            ]
+        AssertCtrlSpaceCompleteContains code "(a." ["GetHashCode"; "CompareTo"] []
+
+
+
+    [<Test>]
+    member public this.``TupledArgsInLambda.Completion.Bug312557_1``() = 
+        let code = 
+            [
+                "[(1,2);(1,2);(1,2)]"
+                "|> Seq.iter (fun (xxx,yyy) -> printfn \"%d\" (*MARKER*)"
+                "                              printfn \"%d\" 1)"
+            ]
+        AssertCtrlSpaceCompleteContains code "(*MARKER*)" ["xxx"; "yyy"] []
+
+    [<Test>]
+    member public this.``TupledArgsInLambda.Completion.Bug312557_2``() = 
+        let code = 
+            [
+                "(1,2) |> (fun (aaa,bbb) ->"
+                "    printfn \"hi\""
+                "    printfn \"%d%d\" b a"
+                "    printfn \"%d%d\" a b   ) "
+            ]
+        AssertCtrlSpaceCompleteContains code "\" b" ["aaa"; "bbb"] []
+        AssertCtrlSpaceCompleteContains code "\" a" ["aaa"; "bbb"] []
+        AssertCtrlSpaceCompleteContains code "b a" ["aaa"; "bbb"] []
+        AssertCtrlSpaceCompleteContains code "a b" ["aaa"; "bbb"] []
+
+
+    [<Test>]
+    [<Category("RangeOperator")>]
+    member public this.``RangeOperator.IncorrectUsage``() = 
+        AssertCtrlSpaceCompletionListIsEmpty [".."] ".."
+        AssertCtrlSpaceCompletionListIsEmpty ["..."] "..."
+    
+    [<Test>]
+    [<Category("Completion in Inherit")>]
+    member public this.``Inherit.CompletionInConstructorArguments1``() = 
+        let code = 
+            [
+                "type A(a : int) = class end"
+                "type B() = inherit A(a)"
+            ]
+        AssertCtrlSpaceCompleteContains code "inherit A(a" ["abs"] []
+
+    [<Test>]
+    [<Category("Completion in Inherit")>]
+    member public this.``Inherit.CompletionInConstructorArguments2``() = 
+        let code = 
+            [
+                "type A(a : int) = class end"
+                "type B() = inherit A(System.String.)"
+            ]
+        AssertCtrlSpaceCompleteContains code "System.String." ["Empty"] ["Array"; "Collections"]
+
+    [<Test>]
+    [<Category("RangeOperator")>]
+    member public this.``RangeOperator.CorrectUsage``() = 
+        let useCases = 
+            [
+                [
+                    "let _ = [1..]"
+                ], "1.."
+                [
+                    "["
+                    "   1"
+                    "    .."
+                    "]"
+                ], ".."
+            ]
+        for (code, marker) in useCases do
+            printfn "%A"  code
+            AssertCtrlSpaceCompleteContains code marker ["abs"] []
+            printfn "ok"
+        
+
+
+    [<Test>]
+    member public this.``Array.Length.InForRange``() =
+        AssertAutoCompleteContainsNoCoffeeBreak 
+          [ "let a = [|1;2;3|]
+for i in 0..a."]
+          "0..a."
+          [ "Length" ] // should contain
+          [ ] // should not contain   
+    
+    [<Test>]
+    member public this.``ProtectedMembers.BaseClass`` () = 
+        let sourceCode = 
+            [
+                "type T() = "
+                "   inherit exn()"
+                "   member this.Run(x : exn) = x."
+            ]
+        AssertCtrlSpaceCompleteContains sourceCode "x." ["Message"; "HResult"] []
+
+    [<Test>]
+    member public this.``ProtectedMembers.SelfOrDerivedClass`` () = 
+        let sources = 
+            [
+                [
+                    "type T() = "
+                    "   inherit exn()"
+                    "   member this.Run(x : T) = x."
+                ]
+                [
+                    "type T() = "
+                    "   inherit exn()"
+                    "   member this.Run(x : Z) = x."
+                    "and Z() ="
+                    "   inherit T()"
+                ]
+            ]
+        for src in sources do
+            AssertCtrlSpaceCompleteContains src "x." ["Message"; "HResult"] []
+
+    
+    [<Test>]
+    [<Ignore("Should be enabled after fixing 279738")>]
+    [<Category("Records")>]
+    member public this.``Records.DotCompletion.ConstructingRecords1``() = 
+        let prologue = "type OuterRec = {XX : int; YY : string}"
+        
+        let useCases = 
+            [
+                "let _ =  (* MARKER*) {X", "(* MARKER*) {X", ["XX"]
+                "let _ = {XX = 1; (* MARKER*)O", "(* MARKER*)O", ["OuterRec"]
+                "let _ = {XX = 1; (* MARKER*)OuterRec.", "(* MARKER*)OuterRec.", ["XX"; "YY"]
+            ]
+        ()
+        for (code, marker, should) in useCases do
+            let code = [prologue; code]
+            AssertCtrlSpaceCompleteContains code marker should ["abs"]
+    
+    [<Test>]
+    [<Category("Records")>]
+    member public this.``Records.DotCompletion.ConstructingRecords2``() = 
+        let prologue = 
+            [
+                "module Mod = "
+                "   type Rec = {XX : int; YY : string}"
+            ]
+        let useCases = 
+            [
+                "let _ = (* MARKER*){X", "(* MARKER*){X", [], ["XX"]
+                "let _ = {(* MARKER*)Mod. = 1; O", "(* MARKER*)Mod.", ["XX"; "YY"], ["System"]
+                "let _ = {(* MARKER*)Mod.Rec. ", "(* MARKER*)Mod.Rec.", ["XX"; "YY"], ["System"]
+            ]
+
+        for (code, marker, should, shouldnot) in useCases do
+            let code = prologue @ [code]
+            let shouldnot = shouldnot @ ["abs"]
+            AssertCtrlSpaceCompleteContains code marker should ["abs"]
+    
+    [<Test>]
+    [<Category("Records")>]
+    member public this.``Records.CopyOnUpdate``() =
+        let prologue = 
+            [
+                "module SomeOtherPath ="
+                "   type r = { a: int; b : int }"
+            ]
+
+        let useCases = 
+            [
+               "let f1 x = { x with SomeOtherPath. = 3 }", "SomeOtherPath."
+               "let f2 x = { x with SomeOtherPath.r. = 3 }", "SomeOtherPath.r."
+               "let f3 (x : SomeOtherPath.r) = { x with }", "x with "
+            ]
+        for (code, marker) in useCases do
+            let code = prologue @ [code]
+            AssertCtrlSpaceCompleteContains code marker ["a"; "b"] ["abs"]
+    
+    [<Test>]
+    [<Category("Records")>]
+    member public this.``Records.CopyOnUpdate.NoFieldsCompletionBeforeWith``() =
+        let code = 
+            [
+                "type T = {AAA : int}"
+                "let r = {AAA = 5}"
+                "let b = {r  with }"
+            ]
+        AssertCtrlSpaceCompleteContains code "{r " [] ["AAA"]
+
+    [<Test>]
+    [<Category("Records")>]
+    member public this.``Records.Constructors1``() =
+        let prologue = 
+            [
+                "type X ="
+                "   val field1 : int"
+                "   val field2 : string"
+            ]
+
+        let useCases = 
+            [
+               "    new() = { f}", "{ f"
+               "    new() = { field1; }", "field1; "
+               "    new() = { field1 = 5; }", "= 5; "
+               "    new() = { field1 = 5; f }", "5; f"
+            ]
+        for (code, marker) in useCases do
+            let code = prologue @ [code]
+            AssertCtrlSpaceCompleteContains code marker ["field1"; "field2"] ["abs"]
+    
+    [<Test>]
+    [<Category("Records")>]
+    member public this.``Records.Constructors2.UnderscoresInNames``() =
+        let prologue = 
+            [
+                "type X ="
+                "   val _field1 : int"
+                "   val _field2 : string"
+            ]
+
+        let useCases = 
+            [
+               "    new() = { _}", "{ _"
+               "    new() = { _field1; }", "_field1; "
+            ]
+        for (code, marker) in useCases do
+            let code = prologue @ [code]
+            AssertCtrlSpaceCompleteContains code marker ["_field1"; "_field2"] ["abs"]  
+
+    
+    [<Test>]
+    [<Category("Records")>]
+    member public this.``Records.NestedRecordPatterns``() =
+        let code = ["[1..({contents = 5}).]"]
+        AssertCtrlSpaceCompleteContains code "5})." ["Value"; "contents"] ["CompareTo"]  
+
+    [<Test>]
+    [<Category("Records")>]
+    member public this.``Records.Separators1``() =
+        let useCases = 
+            [
+                [
+                    "type X = { AAA : int; BBB : string}"
+                    "let r = {AAA = 5 ; }"
+                ], "AAA = 5 "
+                [
+                    "type X = { AAA : int; BBB : string}"
+                    "let r = {AAA = 5 ; }"
+                    "let b = {r with AAA = 5 ; }"
+                ], "with AAA = 5 "
+            ]        
+        
+        for (code, marker) in useCases do
+            printfn "checking separators"
+            printfn "%A" code
+            AssertCtrlSpaceCompleteContains code marker ["abs"] ["AAA"; "BBB"]
+
+    [<Test>]
+    [<Category("Records")>]
+    member public this.``Records.Separators2``() =
+        let useCases = 
+            [
+                "Offside rule", [
+                    "type X = { AAA : int; BBB : string}"
+                    "let r ="
+                    "       {"
+                    "          AAA = 5"
+                    "(*MARKER*)     "
+                    "       }"
+                ], "(*MARKER*)", ["AAA"; "BBB"]
+
+                "Semicolumn", [
+                    "type X = { AAA : int; BBB : string}"
+                    "let r ="
+                    "       {"
+                    "          AAA = 5;"
+                    "(*MARKER*)       "
+                    "       }"
+                ], "(*MARKER*)   ", ["AAA"; "BBB"]
+                "Semicolumn2", [
+                    "type X = { AAA : int; BBB : string; CCC : int}"
+                    "let r ="
+                    "       {"
+                    "          AAA = 5; (*M*)"
+                    "          CCC = 5" 
+                    "       }"
+                ], "(*M*)", ["AAA"; "BBB"; "CCC"]
+            ]        
+        
+        for (caption, code, marker, should) in useCases do
+            printfn "%s" caption
+            printfn "%A" code
+            AssertCtrlSpaceCompleteContains code marker should ["abs"]
+    
+    [<Test>]
+    [<Category("Records")>]
+    member public this.``Records.Inherits``() = 
+        let prologue = 
+            [
+                "type A = class end"
+                "type B = "
+                "   inherit A"
+                "   val f1 : int"
+                "   val f2 : int"
+            ]
+        
+        let useCases = 
+            [
+                ["   new() = { inherit A(); }"], "inherit A(); ", ["f1"; "f2"]
+                [
+                "   new() = { inherit A()"
+                "        (*M*)"
+                "           }"], "(*M*)", ["f1"; "f2"]
+            ]
+        for (code, marker, should) in useCases do
+            let code = prologue @ code
+            printfn "running:"
+            printfn "%s" (String.concat "\r\n" code)
+            AssertCtrlSpaceCompleteContains code marker should ["abs"]
+
+    [<Test>]
+    [<Category("Records")>]
+    member public this.``Records.MissingBindings``() = 
+        let prologue = 
+            [
+                "type R = {AAA : int; BBB : bool}"
+            ]
+        let useCases =
+            [
+                ["let _ = {A = 1; _;  }"], "; _;", ["R"]  // ["AAA"; "BBB"] <- this check should be used after fixing 279738
+                ["let _ = {A = 1; _=; }"], " _=;", ["R"] // ["AAA"; "BBB"] <- this check should be used after fixing 279738
+                ["let _ = {A = 1; R. }"], "1; R.", ["AAA"; "BBB"]
+                ["let _ = {A = 1; _; R. }"], "_; R.", ["AAA"; "BBB"]
+            ]
+
+        for (code, marker, should) in useCases do
+            let code = prologue @ code
+            printfn "running:"
+            printfn "%s" (String.concat "\r\n" code)
+            AssertCtrlSpaceCompleteContains code marker should ["abs"]
+
+    [<Test>]
+    [<Category("Records")>]
+    member public this.``Records.WRONG.MissingBindings``() = 
+        // this test should be removed after fixing 279738
+        let prologue = 
+            [
+                "type R = {AAA : int; BBB : bool}"
+            ]
+        let useCases =
+            [
+                ["let _ = {A = 1; _;  }"], "; _;", ["AAA"; "BBB"]
+                ["let _ = {A = 1; _=; }"], " _=;", ["AAA"; "BBB"]
+            ]
+
+        for (code, marker, shouldNot) in useCases do
+            let code = prologue @ code
+            printfn "running:"
+            printfn "%s" (String.concat "\r\n" code)
+            AssertCtrlSpaceCompleteContains code marker [] shouldNot
+
+
+
+    [<Test>]
+    [<Category("Records")>]
+    member public this.``Records.WRONG.IncorrectNameResEnv``() = 
+        // this test should be removed after fixing 279738
+        let prologue = 
+            [
+                "type R = {AAA : int; BBB : bool; CCC : int}"
+            ]
+        let useCases =
+            [
+                ["let _ = {A}"], "_ = {A", ["AAA"; "BBB"; "CCC"]
+                ["let _ = {AAA = 1; }"], "_ = {AAA = 1;", ["AAA"; "BBB"; "CCC"]
+            ]
+
+        for (code, marker, shouldNot) in useCases do
+            let code = prologue @ code
+            printfn "running:"
+            printfn "%s" (String.concat "\r\n" code)
+            AssertCtrlSpaceCompleteContains code marker [] shouldNot
+
+    [<Test>]
+    [<Category("Records")>]
+    member public this.``Records.WRONG.ErrorsInFirstBinding``() =
+        // errors in the first binding are critical now
+        let prologue = 
+            [
+                "type X ="
+                "   val field1 : int"
+                "   val field2 : string"
+            ]
+
+        let useCases = 
+            [
+               "    new() = { field1 =; }", "=; "  
+               "    new() = { field1 =; f}", "=; f"
+            ]
+        for (code, marker) in useCases do
+            let code = prologue @ [code]
+            AssertCtrlSpaceCompleteContains code marker [] ["field1"; "field2"]
+
+
+    [<Test>]
+    member this.``Completion.DetectInterfaces``() = 
+        let shouldBeInterface =
+            [
+                [
+                    "type X = interface"
+                    "    inherit (*M*)"
+                ]
+                [
+                    "[<Interface>]"
+                    "type X ="
+                    "    inherit (*M*)"
+                ]
+                [
+                    "[<Interface>]"
+                    "type X = interface"
+                    "    inherit (*M*)"
+                ]
+            ]
+        for ifs in shouldBeInterface do
+            AssertCtrlSpaceCompleteContains ifs "(*M*)" ["seq"] ["obj"]
+
+
+    [<Test>]
+    member this.``Completion.DetectClasses``() = 
+    
+        let shouldBeClass = 
+            [
+                [
+                    "type X = class"
+                    "    inherit (*M*)"
+                ]
+                [
+                    "[<Class>]"
+                    "type X ="
+                    "    inherit (*M*)"
+                ]
+                [
+                    "[<Class>]"
+                    "type X = class"
+                    "    inherit (*M*)"
+                ]
+                [
+                    "[<AbstractClass>]"
+                    "type X() = "
+                    "    inherit (*M*)"
+                ]
+            ]
+        for cls in shouldBeClass do
+            AssertCtrlSpaceCompleteContains cls "(*M*)" ["obj"] ["seq"]
+
+    [<Test>]
+    member this.``Completion.DetectUnknownCompletionContext``() = 
+        let content = 
+            [
+                "type X = "
+                "    inherit (*M*)"
+            ]
+
+        AssertCtrlSpaceCompleteContains content "(*M*)" ["obj"; "seq"] ["abs"]
+
+    [<Test>]
+    member this.``Completion.DetectInvalidCompletionContext``() = 
+        let shouldBeInvalid = 
+            [
+                [
+                    "type X = struct"
+                    "    inherit (*M*)"
+                ]
+                [
+                    "[<Interface>]"
+                    "type X = class"
+                    "    inherit (*M*)"
+                ]
+                [
+                    "[<Class>]"
+                    "type X = interface"
+                    "    inherit (*M*)"
+                ]
+                [
+                    "[<Struct>]"
+                    "type X = interface"
+                    "    inherit (*M*)"
+                ]
+                [
+                    "type X ="
+                    "    inherit System (*M*)."
+                ]
+
+                [
+                    "type X ="
+                    "    inherit System (*M*).Collections"
+                ]
+
+            ]
+
+        for invalid in shouldBeInvalid do
+            AssertCtrlSpaceCompletionListIsEmpty invalid "(*M*)"
+
+    
+    [<Test>]
+    member this.``Completion.LongIdentifiers``() = 
+        // System.Diagnostics.Debugger.Launch() |> ignore
+        AssertCtrlSpaceCompleteContains
+            [
+                "type X = "
+                "   inherit System.   "
+            ]
+            "System.   "
+            ["IDisposable"; "Array"]
+            []        
+
+        AssertCtrlSpaceCompleteContains
+            [
+                "type X = "
+                "   inherit System."
+                "             (*M*)"
+            ]
+            "(*M*)"
+            ["IDisposable"; "Array"]
+            []        
+
+        AssertCtrlSpaceCompleteContains
+            [
+                "type X = "
+                "   inherit System"
+                "           .(*M*)"
+            ]
+            "(*M*)"
+            ["IDisposable"; "Array"]
+            []        
+
+        // caret is immediately after marker
+        AssertCtrlSpaceCompleteContains
+            [
+                "module Mod ="
+                "    let x = 1"
+                "module Mod2 = "
+                "    let x = 1"
+                "type X = "
+                "   inherit Mod"
+            ]
+            "  inherit Mod" 
+            ["Mod"; "Mod2"]
+            []        
+        
+        AssertCtrlSpaceCompleteContains
+            [
+                "type X = "
+                "   inherit Sys"
+            ]
+            "Sys"
+            ["System"; "obj"]
+            []        
+
+        AssertCtrlSpaceCompleteContains
+            [
+                "type X = "
+                "   inherit System.Collection"
+            ]
+            "System.Col"
+            ["Collections"; "IDisposable"]
+            []        
+
+
+        AssertCtrlSpaceCompleteContains
+            [
+                "type X = "
+                "   inherit System.  Collections"
+            ]
+            "System. "
+            ["Collections"; "IDisposable"]
+            []        
+
+        AssertCtrlSpaceCompleteContains
+            [
+                "type X = "
+                "   inherit System.  Collections.ArrayList()"
+            ]
+            "System. "
+            ["Collections"; "IDisposable"]
+            []
+
+    [<Test>]
+    member public this.``Query.GroupJoin.CompletionInIncorrectJoinRelations``() = 
+        let code = 
+            [
+                "let t ="
+                "    query {"
+                "        for x in [1] do"
+                "        groupJoin y in [\"\"] on (x. ?=? y.) into g"
+                "        select 1  }"
+            ]
+        AssertCtrlSpaceCompleteContains code "(x." ["CompareTo"] ["abs"]
+        AssertCtrlSpaceCompleteContains code "? y." ["Chars"; "Length"] ["abs"]
+
+    [<Test>]
+    member public this.``Query.Join.CompletionInIncorrectJoinRelations``() = 
+        let code = 
+            [
+                "let t ="
+                "    query {"
+                "        for x in [1] do"
+                "        join y in [\"\"] on (x. ?=? y.)"
+                "        select 1  }"
+            ]
+        AssertCtrlSpaceCompleteContains code "(x." ["CompareTo"] ["abs"]
+        AssertCtrlSpaceCompleteContains code "? y." ["Chars"; "Length"] ["abs"]
+
+    [<Test>]
+    member public this.``Query.ForKeywordCanCompleteIntoIdentifier``() = 
+        let code = 
+            [
+                "let form = 42"
+                "let t ="
+                "    query {"
+                "        for"
+                "    }"
+            ]
+        AssertCtrlSpaceCompleteContains code "for" ["form"] []  // 'for' is a keyword, but should not prevent completion
+    
+    [<Test>]
+    member public this.``ObjInstance.InheritedClass.MethodsWithDiffAccessbility``() =
+        AssertAutoCompleteContainsNoCoffeeBreak 
+          [ "type Base =
+   val mutable baseField : int
+   val mutable private baseFieldPrivate : int
+   new () = { baseField = 0; baseFieldPrivate=1 }
+
+type Derived =
+    val mutable derivedField : int
+    val mutable private derivedFieldPrivate : int
+    inherit Base
+    new () = { derivedField = 0;derivedFieldPrivate = 0 }
+
+let derived = Derived()
+derived.derivedField"]
+          "derived."
+          [ "baseField"; "derivedField" ] // should contain
+          [ "baseFieldPrivate"; "derivedFieldPrivate" ] // should not contain
+
+    [<Test>]
+    member public this.``ObjInstance.InheritedClass.MethodsWithDiffAccessbilityWithSameNameMethod``() =
+        AssertAutoCompleteContainsNoCoffeeBreak 
+          [ "type Base =
+   val mutable baseField : int
+   val mutable private baseFieldPrivate : int
+   new () = { baseField = 0; baseFieldPrivate=1 }
+
+type Derived =
+    val mutable baseField : int
+    val mutable derivedField : int
+    val mutable private derivedFieldPrivate : int
+    inherit Base
+    new () = { baseField = 0; derivedField = 0; derivedFieldPrivate = 0 }
+
+let derived = Derived()
+derived.derivedField"]
+          "derived."
+          [ "baseField"; "derivedField" ] // should contain
+          [ "baseFieldPrivate"; "derivedFieldPrivate" ] // should not contain
+
+    [<Test>]
+    member public this.``Visibility.InheritedClass.MethodsWithDiffAccessibility``() =
+        AssertAutoCompleteContainsNoCoffeeBreak 
+          [ "type Base =
+   val mutable baseField : int
+   val mutable private baseFieldPrivate : int
+   new () = { baseField = 0; baseFieldPrivate=1 }
+
+type Derived =
+    val mutable derivedField : int
+    val mutable private derivedFieldPrivate : int
+    inherit Base
+    new () = { derivedField = 0;derivedFieldPrivate = 0 }
+    member this.Method() =
+        (*marker*)this.baseField"]
+          "(*marker*)this."
+          [ "baseField"; "derivedField"; "derivedFieldPrivate" ] // should contain
+          [ "baseFieldPrivate" ] // should not contain
+
+    [<Test>]
+    member public this.``Visibility.InheritedClass.MethodsWithDiffAccessibilityWithSameNameMethod``() =
+        AssertAutoCompleteContainsNoCoffeeBreak 
+          [ "type Base =
+   val mutable baseField : int
+   val mutable private baseFieldPrivate : int
+   new () = { baseField = 0; baseFieldPrivate=1 }
+
+type Derived =
+    val mutable baseField : int
+    val mutable derivedField : int
+    val mutable private derivedFieldPrivate : int
+    inherit Base
+    new () = { baseField = 0; derivedField = 0; derivedFieldPrivate = 0 }
+    member this.Method() =
+        (*marker*)this.baseField"]
+          "(*marker*)this."
+          [ "baseField"; "derivedField"; "derivedFieldPrivate" ] // should contain
+          [ "baseFieldPrivate" ] // should not contain
+
+    [<Test>]
+    member public this.``Visibility.InheritedClass.MethodsWithSameNameMethod``() =
+        AssertAutoCompleteContainsNoCoffeeBreak 
+          [ "type MyClass =
+    val foo : int
+    new (foo) = { foo = foo }
+ 
+type MyClass2 =
+    inherit MyClass
+    val foo : int
+    new (foo) = {
+        inherit MyClass(foo)
+        foo = foo
+        }
+
+let x = new MyClass2(0)
+(*marker*)x.foo"]
+          "(*marker*)x."
+          [ "foo" ] // should contain
+          [ ] // should not contain
+
+    [<Test>]
+    member public this.``Identifier.Array.AfterassertKeyword``() =
+        AssertAutoCompleteContainsNoCoffeeBreak 
+          [ "let x = [1;2;3] "
+            "assert x." ]
+          "x."
+          [ "Head" ] // should contain (from List<int>)
+          [ "Listeners" ] // should not contain (from System.Diagnostics.Debug)
+
+    [<Test>]
+    member public this.``CtrlSpaceCompletion.Bug130670.Case1``() =
+        AssertCtrlSpaceCompleteContainsNoCoffeeBreak 
+          [ "let i = async.Return(4)" ]
+          ")"
+          [ "AbstractClassAttribute" ] // should contain (top-level)
+          [ "GetType" ] // should not contain (object instance method)
+
+    [<Test>]
+    member public this.``CtrlSpaceCompletion.Bug130670.Case2``() =
+        AssertCtrlSpaceCompleteContainsNoCoffeeBreak 
+          [ """
+                let x = 42 
+                let r = x + 1 """ ]
+          "1 "
+          [ "AbstractClassAttribute" ] // should contain (top-level)
+          [ "CompareTo" ] // should not contain (instance method on int)
+
+    [<Test>]
+    member public this.``CtrlSpaceCompletion.Bug294974.Case1``() =
+        
+        AssertCtrlSpaceCompleteContains
+          [ """
+              let xxx = [1]
+         (*M*)xxx.IsEmpty // Ctrl-J just before the '.'""" ]
+          "(*M*)xxx"
+          [ "xxx" ] // should contain (completions before dot)
+          [ "IsEmpty" ] // should not contain (completions after dot)
+
+    [<Test>]
+    member public this.``CtrlSpaceCompletion.Bug294974.Case2``() =
+        AssertCtrlSpaceCompleteContains
+          [ """
+              let xxx = [1]
+              xxx .IsEmpty // Ctrl-J just before the '.' """ ]
+          "xxx "
+          [ "AbstractClassAttribute" ] // should contain (top-level)
+          [ "IsEmpty" ] // should not contain (completions after dot)
+
+    [<Test>]
+    member public this.``ObsoleteProperties.6377_1``() =
+        AssertAutoCompleteContainsNoCoffeeBreak 
+          [ "System.Security.SecurityManager." ]
+          "SecurityManager."
+          [ "GetStandardSandbox" ] // should contain
+          [ "get_SecurityEnabled"; "set_SecurityEnabled" ] // should not contain
+
+    [<Test>]
+    member public this.``ObsoleteProperties.6377_2``() =
+        AssertAutoCompleteContainsNoCoffeeBreak 
+          [ "System.Threading.Thread.CurrentThread." ]
+          "CurrentThread."
+          [ "CurrentCulture" ] // should contain: just make sure something shows
+          [ "get_ApartmentState"; "set_ApartmentState" ] // should not contain
+
+    [<Test>]
+    member public this.``PopupsVersusCtrlSpaceOnDotDot.FirstDot.Popup``() =
+        AssertAutoCompleteContainsNoCoffeeBreak 
+          [ "System.Console..BackgroundColor" ]
+          "System.Console."
+          [ "BackgroundColor" ] // should contain (from prior System.Console)
+          [ "abs" ] // should not contain (top-level autocomplete on empty identifier)
+
+    [<Test>]
+    member public this.``PopupsVersusCtrlSpaceOnDotDot.FirstDot.CtrlSpace``() =
+        AssertCtrlSpaceCompleteContainsNoCoffeeBreak 
+          [ "System.Console..BackgroundColor" ]
+          "System.Console."
+          [ "BackgroundColor" ] // should contain (from prior System.Console)
+          [ "abs" ] // should not contain (top-level autocomplete on empty identifier)
+
+    [<Test>]
+    member public this.``PopupsVersusCtrlSpaceOnDotDot.SecondDot.Popup``() =
+        // Salsa is no yet capable of determining whether there would be a popup, it can only test what would appear if there were.
+        // So can't do test below.
+//        AssertAutoCompleteContainsNoCoffeeBreak 
+//          [ "System.Console..BackgroundColor" ]
+//          "System.Console.."
+//          [ ] // should be empty - in fact, there is no popup here
+//          [ "abs"; "BackgroundColor" ] // should not contain anything
+        ()
+
+    [<Test>]
+    member public this.``PopupsVersusCtrlSpaceOnDotDot.SecondDot.CtrlSpace``() =
+        AssertCtrlSpaceCompleteContainsNoCoffeeBreak 
+          [ "System.Console..BackgroundColor" ]
+          "System.Console.."
+          [ ] // should contain nothing - .. is not properly used range operator
+          [ "abs" ] // should not contain (from prior System.Console)
+    
+    [<Test>]
+    member public this.``DotCompletionInPatternsPartOfLambda``() = 
+        let content = ["let _ = fun x . -> x + 1"]
+        AssertCtrlSpaceCompletionListIsEmpty content "x ."
+
+    [<Test>]
+    member public this.``DotCompletionInBrokenLambda``() = 
+        let content = ["1 |> id (fun x .> x)"]
+        AssertCtrlSpaceCompletionListIsEmpty content "x ."
+
+    [<Test>]
+    member public this.``DotCompletionInPatterns``() = 
+        let useCases = 
+            [
+                ["let (x, y .) = 1, 2"], "y ."
+                ["let run (o : obj) = match o with | :? int as i . -> 1 | _ -> 0"], "as i ."
+                ["let (``x.y``, ``y.z`` .) = 1, true"], "z`` ."
+                ["let ``x`` . = 1"], "x`` ."
+            ]
+        for (source, marker) in useCases do
+            AssertCtrlSpaceCompletionListIsEmpty source marker
+
+
+    [<Test>]
+    member public this.``DotCompletionWithBrokenLambda``() = 
+        let errors = 
+            [
+                "1 |> id (fun)"
+                "1 |> id (fun x > x)"
+                "1 |> id (fun x > )"
+                "1 |> id (fun x -> )"
+            ]
+        let testcases = 
+            [
+                for error in errors do
+                    let source = 
+                        [
+                            "let x = 1"
+                            "x."
+                        ]
+                    yield (error::source), "x.", ["CompareTo"], ["Array"]
+                    yield (source @ [error]), "x.", ["CompareTo"], ["Array"]
+            ]
+        for (source, marker, should, shouldnot) in testcases do
+            printfn "%A" source
+            AssertCtrlSpaceCompleteContains source marker should shouldnot
+
+
+    [<Test>]
+    member public this.``AfterConstructor.5039_1``() =
+        AssertAutoCompleteContainsNoCoffeeBreak 
+          [ "let someCall(x) = null"
+            "let xe = someCall(System.IO.StringReader()." ]
+          "StringReader()."
+          [ "ReadBlock" ] // should contain (StringReader)
+          [ "LastIndexOfAny" ] // should not contain (String)
+
+    [<Test>]
+    member public this.``AfterConstructor.5039_1.CoffeeBreak``() =
+        AssertAutoCompleteContains
+          [ "let someCall(x) = null"
+            "let xe = someCall(System.IO.StringReader()." ]
+          "StringReader()."
+          [ "ReadBlock" ] // should contain (StringReader)
+          [ "LastIndexOfAny" ] // should not contain (String)
+
+    [<Test>]
+    member public this.``AfterConstructor.5039_2``() =
+        AssertAutoCompleteContainsNoCoffeeBreak 
+          [ "System.Random()." ]
+          "Random()."
+          [ "NextDouble" ] // should contain
+          [ ] // should not contain
+
+    [<Test>]
+    member public this.``AfterConstructor.5039_3``() =
+        AssertAutoCompleteContainsNoCoffeeBreak 
+          [ "System.Collections.Generic.List<int>()." ]
+          "List<int>()."
+          [ "BinarySearch" ] // should contain
+          [ ] // should not contain
+
+    [<Test>]
+    member public this.``AfterConstructor.5039_4``() =
+        AssertAutoCompleteContainsNoCoffeeBreak 
+          [ "System.Collections.Generic.List()." ]
+          "List()."
+          [ "BinarySearch" ] // should contain
+          [ ] // should not contain
+
+    [<Test>]
+    member public this.``Literal.809979``() =
+        AssertAutoCompleteContainsNoCoffeeBreak 
+          [ "let value=uint64." ]
+          "uint64."
+          [ ] // should contain
+          [ "Parse" ] // should not contain
+
+    [<Test>]
+    member public this.``NameSpace.AsConstructor``() =        
+        AssertCtrlSpaceCompleteContainsNoCoffeeBreak 
+          [ "new System.DateTime()" ]
+          "System.DateTime("  // move to marker
+          ["System";"Array2D"]
+          ["DaysInMonth"; "AddDays" ] // should contain top level info, no static or instance DateTime members!
+         
+    [<Test>]
+    member public this.``DotAfterApplication1``() = 
+        AssertAutoCompleteContainsNoCoffeeBreak
+          ["let g a = new System.Random()"
+           "(g [])."]
+          "(g [])."
+          ["Next"]
+          [ ]
+
+    [<Test>]
+    member public this.``DotAfterApplication2``() = 
+        AssertAutoCompleteContainsNoCoffeeBreak
+          ["let g a = new System.Random()"
+           "g []."]
+          "g []."
+          ["Head"]
+          [ ]
+
+    [<Test>]
+    member public this.``Quickinfo.809979``() =
+        AssertAutoCompleteContainsNoCoffeeBreak 
+          [ "let value=uint64." ]
+          "uint64."
+          [ ] // should contain
+          [ "Parse" ] // should not contain
+
+    /// No intellisense in comments/strings!
+    [<Test>]
+    member public this.``InString``() = 
+        this.VerifyCtrlSpaceCompListIsEmptyAtEndOfMarker(
+            fileContents = """ // System.C """ ,  
+            marker = "// System.C" )
+    [<Test>]
+    member public this.``InComment``() = 
+        this.VerifyCtrlSpaceCompListIsEmptyAtEndOfMarker(
+            fileContents = """ let s = "System.C" """,
+            marker = "\"System.C")
+                 
+    /// Intellisense at the top level (on white space)
+    [<Test;Category("Repro")>]
+    member public this.``Identifier.OnWhiteSpace.AtTopLevel``() =  
+        AssertCtrlSpaceCompleteContainsNoCoffeeBreak
+          ["(*marker*)  "] 
+          "(*marker*) " 
+          ["System"; "Array2D"]
+          ["Int32"]
+     
+    /// Intellisense at the top level (after a partial token). All matches should be shown even if there is a unique match
+    [<Test;Category("Repro")>]
+    member public this.``TopLevelIdentifier.AfterPartialToken1``() =  
+        AssertCtrlSpaceCompleteContainsNoCoffeeBreak
+          ["let foobaz = 1"
+           "(*marker*)fo"] 
+          "(*marker*)fo"
+          ["System";"Array2D";"foobaz"]
+          ["Int32"]
+
+    [<Test;Category("Repro")>]
+    member public this.``TopLevelIdentifier.AfterPartialToken2``() =  
+        AssertCtrlSpaceCompleteContainsNoCoffeeBreak
+          ["let foobaz = 1"
+           "(*marker*)fo"] 
+          "(*marker*)"
+          ["System";"Array2D";"foobaz"]
+          []
+
+(* these issues have not been fixed yet, but when they are, here are some tests
+    [<Test>]
+    member public this.``AutoComplete.Bug65730``() =        
+        AssertAutoCompleteContains 
+          [ "let f x y = x.Equals(y)" ]
+          "x."       // marker
+          [ "Equals" ] // should contain
+          [  ] // should not contain
+
+    [<Test>]
+    member public this.``AutoComplete.Bug65731_A``() =        
+        AssertAutoCompleteContains 
+          [ 
+@"module SomeOtherPath ="
+@"    type r = { a: int; b : int }"
+@"let f1 x = { x with SomeOtherPath.a = 3 } // a"
+           ]
+          "SomeOtherPath."       // marker
+          [ "a" ] // should contain
+          [  ] // should not contain
+
+    [<Test>]
+    member public this.``AutoComplete.Bug65731_B``() =        
+        AssertAutoCompleteContains 
+          [ 
+@"module SomeOtherPath ="
+@"    type r = { a: int; b : int }"
+@"let f2 x = { x with SomeOtherPath.r.a = 3 } // a"
+           ]
+          "SomeOtherPath.r."       // marker
+          [ "a" ] // should contain
+          [  ] // should not contain
+
+    [<Test>]
+    member public this.``AutoComplete.Bug69654_0``() =        
+        let code = [ @"
+                        let q =
+                            let a = 42
+                            let b = (fun i -> i) 43
+                            // i shows up in Ctrl-space list here, b does not
+                            ((* *)) // but in the parens, things are correct again
+                        "]
+
+        let solution = CreateSolution(this.VS)
+        let project = CreateProject(solution,"testproject")
+        let file = AddFileFromText(project,"File1.fs", code)
+        let file = OpenFile(project,"File1.fs")
+        TakeCoffeeBreak(this.VS)
+        let gpatcc = GlobalParseAndTypeCheckCounter.StartNew(this.VS)
+
+        MoveCursorToStartOfMarker(file, "//")
+        let completions = AutoCompleteAtCursor file
+        AssertCompListContains(completions, "b")
+        AssertCompListDoesNotContain(completions, "i")
+
+        MoveCursorToStartOfMarker(file, "(* *)")
+        let completions = AutoCompleteAtCursor file
+        AssertCompListContains(completions, "b")
+        AssertCompListDoesNotContain(completions, "i")
+
+        gpatcc.AssertExactly(0,0)
+
+    [<Test>]
+    member public this.``AutoComplete.Bug69654_1``() =        
+        let code = [ 
+                    "let s = async {"
+                    "            let! xxx = async { return 0 }"
+                    "            xxx.CompareTo |> ignore // the dot works"
+                    "            xxx |> ignore // no xxx"
+                    "            do xxx |> ignore // no xxx"
+                    "            return xxx // no xxx"
+                    "        }" ]
+        let solution = CreateSolution(this.VS)
+        let project = CreateProject(solution,"testproject")
+        let file = AddFileFromText(project,"File1.fs", code)
+        let file = OpenFile(project,"File1.fs")
+        TakeCoffeeBreak(this.VS)
+        let gpatcc = GlobalParseAndTypeCheckCounter.StartNew(this.VS)
+
+        MoveCursorToEndOfMarker(file, "xx.Comp")
+        let completions = AutoCompleteAtCursor file
+        AssertCompListContains(completions, "CompareTo")
+
+        MoveCursorToStartOfMarker(file, "xx.Comp")
+        let completions = AutoCompleteAtCursor file
+        AssertCompListContains(completions, "xxx")
+
+        MoveCursorToStartOfMarker(file, "xx |>")
+        let completions = AutoCompleteAtCursor file
+        AssertCompListContains(completions, "xxx")
+
+        MoveCursorToEndOfMarker(file, "do xx")
+        let completions = AutoCompleteAtCursor file
+        AssertCompListContains(completions, "xxx")
+
+        MoveCursorToEndOfMarker(file, "return xx")
+        let completions = AutoCompleteAtCursor file
+        AssertCompListContains(completions, "xxx")
+
+        gpatcc.AssertExactly(0,0)
+
+    [<Test>]
+    member public this.``AutoComplete.Bug69654_2``() =        
+        let code = [ 
+                    "let s = async {"
+                    "            use xxx = null"
+                    "            xxx.Dispose() // the dot works"
+                    "            xxx |> ignore // no xxx"
+                    "            do xxx |> ignore // no xxx"
+                    "            return xxx // no xxx"
+                    "        }" ]
+        let solution = CreateSolution(this.VS)
+        let project = CreateProject(solution,"testproject")
+        let file = AddFileFromText(project,"File1.fs", code)
+        let file = OpenFile(project,"File1.fs")
+        TakeCoffeeBreak(this.VS)
+        let gpatcc = GlobalParseAndTypeCheckCounter.StartNew(this.VS)
+
+        MoveCursorToEndOfMarker(file, "xx.Disp")
+        let completions = AutoCompleteAtCursor file
+        AssertCompListContains(completions, "Dispose")
+
+        MoveCursorToStartOfMarker(file, "xx.Disp")
+        let completions = AutoCompleteAtCursor file
+        AssertCompListContains(completions, "xxx")
+
+        MoveCursorToStartOfMarker(file, "xx |>")
+        let completions = AutoCompleteAtCursor file
+        AssertCompListContains(completions, "xxx")
+
+        MoveCursorToEndOfMarker(file, "do xx")
+        let completions = AutoCompleteAtCursor file
+        AssertCompListContains(completions, "xxx")
+
+        MoveCursorToEndOfMarker(file, "return xx")
+        let completions = AutoCompleteAtCursor file
+        AssertCompListContains(completions, "xxx")
+
+        gpatcc.AssertExactly(0,0)
+*)
+
+    [<Test>]
+    member public this.``List.AfterAddLinqNamespace.Bug3754``() =        
+        let code = 
+                ["open System.Xml.Linq"
+                 "List." ]
+        let (_, _, file) = this.CreateSingleFileProject(code, references = ["System.Xml"; "System.Xml.Linq"])
+        MoveCursorToEndOfMarker(file, "List.")
+        let completions = AutoCompleteAtCursor file
+        AssertCompListContainsAll(completions, [ "map"; "filter" ] )
+
+    [<Test>]
+    member public this.``Global``() =    
+        AssertAutoCompleteContainsNoCoffeeBreak
+          ["global."]
+          "global."
+          ["System"; "Microsoft" ]
+          []
+
+    [<Test>]
+    member public this.``Duplicates.Bug4103a``() =        
+        let code = 
+            [ 
+                "open Microsoft.FSharp.Quotations"
+                "Expr." ]
+        let (_, _, file) = this.CreateSingleFileProject(code)
+        MoveCursorToEndOfMarker(file, "Expr.")
+        let completions = AutoCompleteAtCursor file
+        
+        // Get description for Expr.Var
+        let (_, _, descrFunc, _) = completions |> Array.find (fun (name, _, _, _) -> name = "WhileLoop")
+        let descr = descrFunc()
+        // Check whether the description contains the name only once        
+        let occurrences = ("  " + descr + "  ").Split([| "WhileLoop" |], System.StringSplitOptions.None).Length - 1
+        // You'll get two occurrances - one for the signature, and one for the doc
+        AssertEqualWithMessage(2, occurrences, "The entry for 'Expr.Var' is duplicated.")
+      
+    /// Testing autocomplete after a dot directly following method call
+    [<Test>]
+    member public this.``AfterMethod.Bug2296``() =        
+        AssertAutoCompleteContainsNoCoffeeBreak
+          [ "type System.Int32 with"
+            "  member x.Int32Member() = 0"
+            "\"\".CompareTo(\"a\")." ]
+          "(\"a\")."
+          ["Int32Member" ]
+          []
+
+    /// Testing autocomplete after a dot directly following overloaded method call
+    [<Test>]
+    member public this.``AfterMethod.Overloaded.Bug2296``() =      
+        AssertAutoCompleteContainsNoCoffeeBreak
+          ["type System.Boolean with"
+           "  member x.BooleanMember() = 0"
+           "\"\".Contains(\"a\")."]
+          "(\"a\")."
+          ["BooleanMember"]
+          []
+
+    [<Test;Category("Repro")>]
+    member public this.``BasicGlobalMemberList``() =  
+        AssertAutoCompleteContainsNoCoffeeBreak
+          ["let x = 1"
+           "x."]
+          "x."
+          ["CompareTo"; "GetHashCode"]
+          []
+
+    [<Test;Category("Repro")>]
+    member public this.``CharLiteral``() =  
+        AssertAutoCompleteContainsNoCoffeeBreak
+          ["let x = \"foo\""
+           "let x' = \"bar\""
+           "x'."]
+          "x'."
+          ["CompareTo";"GetHashCode"]
+          []
+
+    [<Test;Category("Repro")>]
+    member public this.``GlobalMember.ListOnIdentifierEndingWithTick``() =      
+        AssertAutoCompleteContainsNoCoffeeBreak
+          ["let x' = 1"
+           "x'."]
+          "x'."
+          ["CompareTo";"GetHashCode"]
+          []
+
+    [<Test;Category("Repro")>]
+    member public this.``GlobalMember.ListOnIdentifierContainingTick``() =   
+        AssertAutoCompleteContainsNoCoffeeBreak
+          ["let x'y = 1"
+           "x'y."]
+          "x'y."
+          ["CompareTo";"GetHashCode"]
+          []
+        
+    [<Test;Category("Repro")>]
+    member public this.``GlobalMember.ListWithPartialMember1``() =    
+        AssertCtrlSpaceCompleteContainsNoCoffeeBreak
+          ["let x = 1"
+           "x.CompareT"]
+          "x.CompareT"
+          ["CompareTo";"GetHashCode"]
+          []
+
+    [<Test;Category("Repro")>]
+    member public this.``GlobalMember.ListWithPartialMember2``() =    
+        AssertAutoCompleteContainsNoCoffeeBreak
+          ["let x = 1"
+           "x.CompareT"]
+          "x."
+          ["CompareTo";"GetHashCode"]
+          []
+
+    /// Wrong intellisense for array              
+    [<Test;Category("Repro")>]
+    member public this.``DotOff.Parenthesized.Expr``() =       
+        AssertAutoCompleteContainsNoCoffeeBreak
+          ["let string_of_int (x:int) = x.ToString()"
+           "let strs = Array.init 10 string_of_int"
+           "let x = (strs.[1])."]
+          "(strs.[1])."
+          ["Substring";"GetHashCode"]
+          []
+
+    /// Wrong intellisense for array
+    [<Test;Category("Repro")>]
+    member public this.``DotOff.ArrayIndexerNotation``() =  
+        AssertAutoCompleteContainsNoCoffeeBreak
+          ["let string_of_int (x:int) = x.ToString()"
+           "let strs = Array.init 10 string_of_int"
+           "let test1 = strs.[1]."]
+          "strs.[1]."
+          ["Substring";"GetHashCode"]
+          []
+
+    /// Wrong intellisense for array
+    [<Test;Category("Repro")>]
+    member public this.``DotOff.ArraySliceNotation1``() =    
+        AssertAutoCompleteContainsNoCoffeeBreak
+          ["let string_of_int (x:int) = x.ToString()"
+           "let strs = Array.init 10 string_of_int"
+           "let test2 = strs.[1..]."
+           "let test3 = strs.[..1]."
+           "let test4 = strs.[1..1]."]
+          "trs.[1..]."
+          ["Length"]
+          []
+
+    [<Test;Category("Repro")>]
+    member public this.``DotOff.ArraySliceNotation2``() =    
+        AssertAutoCompleteContainsNoCoffeeBreak
+          ["let string_of_int (x:int) = x.ToString()"
+           "let strs = Array.init 10 string_of_int"
+           "let test2 = strs.[1..]."
+           "let test3 = strs.[..1]."
+           "let test4 = strs.[1..1]."]
+          "strs.[..1]."
+          ["Length"]
+          []
+
+    [<Test;Category("Repro")>]
+    member public this.``DotOff.ArraySliceNotation3``() =    
+        AssertAutoCompleteContainsNoCoffeeBreak
+          ["let string_of_int (x:int) = x.ToString()"
+           "let strs = Array.init 10 string_of_int"
+           "let test2 = strs.[1..]."
+           "let test3 = strs.[..1]."
+           "let test4 = strs.[1..1]."]
+          "strs.[1..1]."
+          ["Length"]
+          []
+           
+    [<Test;Category("Repro")>]
+    member public this.``DotOff.DictionaryIndexer``() =        
+        AssertAutoCompleteContainsNoCoffeeBreak
+          ["let dict = new System.Collections.Generic.Dictionary<int,string>()"
+           "let test5 = dict.[1]."]
+          "dict.[1]."
+          ["Length"]
+          []
+
+    /// intellisense on DOT
+    [<Test;Category("Repro")>]
+    member public this.``EmptyFile.Dot.Bug1115``() =   
+        this.VerifyAutoCompListIsEmptyAtEndOfMarker(
+            fileContents = "." ,
+            marker = ".")    
+
+    [<Test;Category("Repro")>]
+    member public this.``Identifier.NonDottedNamespace.Bug1347``() =     
+        this.AssertCtrlSpaceCompletionContains(
+            ["open System"
+             "open Microsoft.FSharp.Math"
+             "let x = Mic"
+             "let p7 ="
+             "    let seive limit = "
+             "        let isPrime = Array.create (limit+1) true"
+             "        for n in"],
+            "let x = Mic",
+            "Microsoft")
+
+    [<Test;Category("Repro")>]
+    member public this.``MatchStatement.WhenClause.Bug2519``() =   
+        AssertAutoCompleteContainsNoCoffeeBreak
+          ["type DU = X of int"
+           "let timefilter pkt ="
+           "    match pkt with"
+           "    | X(hdr) when (*aaa*)hdr."
+           "    | _ -> ()"]
+          "(*aaa*)hdr."
+          ["CompareTo";"GetHashCode"]
+          []
+        
+    [<Test;Category("Repro")>]
+    member public this.``String.BeforeIncompleteModuleDefinition.Bug2385``() =     
+        AssertAutoCompleteContainsNoCoffeeBreak
+          ["let s = \"hello\"."
+           "module Timer ="]
+          "\"hello\"."
+          ["Substring";"GetHashCode"]
+          []
+
+    [<Test>]
+    [<Category("PerfCheck")>]
+    member public this.``Project.FsFileWithBuildAction``() =
+        AssertAutoCompleteContainsNoCoffeeBreak
+          ["let i = 4"
+           "let r = i.ToString()"
+           "let x = File1.bob"]
+          "i."
+          ["CompareTo"]
+          []
+
+     /// Dotting off a string literal should work.
+    [<Test;Category("Repro")>]
+    member public this.``DotOff.String``() =
+        AssertAutoCompleteContainsNoCoffeeBreak
+          ["\"x\". (*marker*)"
+           ""]
+          "\"x\"."
+          ["Substring";"GetHashCode"]
+          []
+                   
+    /// FEATURE: Pressing dot (.) after an local variable will produce an Intellisense list of members the user may select.
+    [<Test;Category("Repro")>]
+    member public this.``BasicLocalMemberList``() = 
+        AssertAutoCompleteContainsNoCoffeeBreak 
+          ["let MyFunction (s:string) = "
+           "    let y=\"dog\""
+           "    y."
+           "    ()"]
+          "    y."
+          ["Substring";"GetHashCode"]
+          []
+
+    [<Test;Category("Repro")>]
+    member public this.``LocalMemberList.WithPartialMemberEntry1``() = 
+        AssertCtrlSpaceCompleteContainsNoCoffeeBreak
+          ["let MyFunction (s:string) = "
+           "    let y=\"dog\""
+           "    y.Substri"
+           "    ()"]
+          "    y.Substri"
+          ["Substring";"GetHashCode"]
+          []
+
+    [<Test;Category("Repro")>]
+    member public this.``LocalMemberList.WithPartialMemberEntry2``() = 
+        AssertAutoCompleteContainsNoCoffeeBreak
+          ["let MyFunction (s:string) = "
+           "    let y=\"dog\""
+           "    y.Substri"
+           "    ()"]
+          "    y."
+          ["Substring";"GetHashCode"]
+          []
+
+    [<Test;Category("Repro")>]
+    member public this.``CurriedArguments.Regression1``() = 
+        AssertCtrlSpaceCompleteContainsNoCoffeeBreak  
+           ["let fffff x y = 1"
+            "let ggggg  = 1"
+            "let test1 = fffff \"a\" ggggg"
+            "let test2 = fffff 1 ggggg"
+            "let test3 = fffff ggggg ggggg"] 
+           "let f"
+           ["fffff"]
+           []   
+           
+    [<Test;Category("Repro")>]
+    member public this.``CurriedArguments.Regression2``() = 
+        AssertCtrlSpaceCompleteContainsNoCoffeeBreak  
+           ["let fffff x y = 1"
+            "let ggggg  = 1"
+            "let test1 = fffff \"a\" ggggg"
+            "let test2 = fffff 1 ggggg"
+            "let test3 = fffff ggggg ggggg"] 
+           "let test1 = f"
+           ["fffff"]
+           []       
+           
+    [<Test;Category("Repro")>]
+    member public this.``CurriedArguments.Regression3``() = 
+        AssertCtrlSpaceCompleteContainsNoCoffeeBreak  
+           ["let fffff x y = 1"
+            "let ggggg  = 1"
+            "let test1 = fffff \"a\" ggggg"
+            "let test2 = fffff 1 ggggg"
+            "let test3 = fffff ggggg ggggg"] 
+           "let test1 = fffff \"a\" gg"
+           ["ggggg"]
+           []                                 
+      
+    [<Test;Category("Repro")>]
+    member public this.``CurriedArguments.Regression4``() = 
+        AssertCtrlSpaceCompleteContainsNoCoffeeBreak  
+           ["let fffff x y = 1"
+            "let ggggg  = 1"
+            "let test1 = fffff \"a\" ggggg"
+            "let test2 = fffff 1 ggggg"
+            "let test3 = fffff ggggg ggggg"] 
+           "let test2 = fffff 1 gg"
+           ["ggggg"]
+           []
+
+    [<Test;Category("Repro")>]
+    member public this.``CurriedArguments.Regression5``() = 
+        AssertCtrlSpaceCompleteContainsNoCoffeeBreak  
+           ["let fffff x y = 1"
+            "let ggggg  = 1"
+            "let test1 = fffff \"a\" ggggg"
+            "let test2 = fffff 1 ggggg"
+            "let test3 = fffff ggggg ggggg"] 
+           "let test3 = fffff gg"
+           ["ggggg"]
+           []
+
+    [<Test;Category("Repro")>]
+    member public this.``CurriedArguments.Regression6``() = 
+        AssertCtrlSpaceCompleteContainsNoCoffeeBreak  
+           ["let fffff x y = 1"
+            "let ggggg  = 1"
+            "let test1 = fffff \"a\" ggggg"
+            "let test2 = fffff 1 ggggg"
+            "let test3 = fffff ggggg ggggg"] 
+           "let test3 = fffff ggggg gg"
+           ["ggggg"]
+           []
+
+    // Test whether standard types appear in the completion list under both F# and .NET name
+    [<Test>]
+    member public this.``StandardTypes.Bug4403``() = 
+        AssertCtrlSpaceCompleteContainsNoCoffeeBreak
+          ["open System"; "let x=" ]
+          "let x="
+          ["int8"; "int16"; "int32"; "string"; "SByte"; "Int16"; "Int32"; "String" ]
+          [ ]
+
+    // Test whether standard types appear in the completion list under both F# and .NET name            
+    [<Test>]
+    member public this.``ValueDeclarationHidden.Bug4405``() = 
+        AssertAutoCompleteContainsNoCoffeeBreak
+          [ "do  "
+            "  let a = \"string\""
+            "  let a = if true then 0 else a."]
+          "else a."
+          ["IndexOf"; "Substring"]
+          [ ]
+
+    [<Test>]
+    member public this.``StringFunctions``() = 
+        let code = 
+            [
+                "let y = String."
+                "let f x = 0"
+            ]
+        let (_, _, file) = this.CreateSingleFileProject(code)
+        MoveCursorToEndOfMarker(file,"String.")
+        let completions = time1 AutoCompleteAtCursor file "Time of first autocomplete."
+        // printf "Completions=%A\n" completions
+        Assert.IsTrue(completions.Length>0)
+        for completion in completions do
+            match completion with 
+              | _,_,_,DeclarationType.FunctionValue -> ()
+              | name,_,_,x -> failwith (sprintf "Unexpected item %s seen with declaration type %A" name x)
+                         
+    // FEATURE: Pressing ctrl+space or ctrl+j will give a list of valid completions.
+    
+    [<Test>]
+    //Verified atleast "Some" is contained in the Ctrl-Space Completion list
+    member public this.``NonDotCompletion``() =  
+        this.AssertCtrlSpaceCompletionContains(
+            ["let x = S"],
+            "x = S",
+            "Some")
+     
+    [<Test>]
+    [<Category("TypeProvider")>]
+    [<Category("TypeProvider.EditorHideMethodsAttribute")>]
+    // This test case checks Pressing ctrl+space on the provided Type instance method shows list of valid completions
+    member this.``TypeProvider.EditorHideMethodsAttribute.InstanceMethod.CtrlSpaceCompletionContains``() =
+        this.AssertCtrlSpaceCompletionContains(
+            fileContents = [""" 
+                                let t = new N1.T1()
+                                t.I"""],
+            marker = "t.I",
+            expected = "IM1",    
+            addtlRefAssy = [System.IO.Path.Combine(System.Environment.CurrentDirectory, @"UnitTestsResources\MockTypeProviders\DummyProviderForLanguageServiceTesting.dll")])
+    
+    [<Test>]
+    [<Category("TypeProvider")>]
+    [<Category("TypeProvider.EditorHideMethodsAttribute")>]
+    // This test case checks Pressing ctrl+space on the provided Type Event shows list of valid completions
+    member this.``TypeProvider.EditorHideMethodsAttribute.Event.CtrlSpaceCompletionContains``() =
+        this.AssertCtrlSpaceCompletionContains(
+            fileContents = [""" 
+                                let t = new N.T()
+                                t.Eve"""],
+            marker = "t.Eve", 
+            expected = "Event1",          
+            addtlRefAssy = [System.IO.Path.Combine(System.Environment.CurrentDirectory, @"UnitTestsResources\MockTypeProviders\EditorHideMethodsAttribute.dll")])
+     
+    [<Test>]
+    [<Category("TypeProvider")>]
+    [<Category("TypeProvider.EditorHideMethodsAttribute")>]
+    // This test case checks Pressing ctrl+space on the provided Type static parameter and verify "int" is in the list just to make sure bad things don't happen and autocomplete window pops up
+    member this.``TypeProvider.EditorHideMethodsAttribute.Type.CtrlSpaceCompletionContains``() =
+        this.AssertCtrlSpaceCompletionContains(
+            fileContents = [""" 
+                                type boo = N1.T<in"""],
+            marker = "T<in",  
+            expected = "int",  
+            addtlRefAssy = [System.IO.Path.Combine(System.Environment.CurrentDirectory, @"UnitTestsResources\MockTypeProviders\DummyProviderForLanguageServiceTesting.dll")])
+    
+        
+    // In this bug, pressing dot after this was producing an invalid member list.       
+    [<Test>]
+    member public this.``Class.Self.Bug1544``() =     
+        this.VerifyAutoCompListIsEmptyAtEndOfMarker(
+            fileContents = "
+                type Foo() =
+                    member this.",
+            marker = "this.")
+
+    // No completion list at the end of file. 
+    [<Test>]
+    member public this.``Idenfitier.AfterDefined.Bug1545``() = 
+        this.AutoCompletionListNotEmpty
+            ["let x = [|\"hello\"|]"
+             "x."]
+            "x."                              
+
+    [<Test>]
+    member public this.``Bug243082.DotAfterNewBreaksCompletion`` () = 
+        this.AutoCompletionListNotEmpty
+            [
+            "module A ="
+            "    type B() = class end"
+            "let s = 1"
+            "s."
+            "let z = new A."]
+            "s."        
+
+    [<Test>]
+    member public this.``Bug243082.DotAfterNewBreaksCompletion2`` () = 
+        this.AutoCompletionListNotEmpty
+            [
+            "let s = 1"
+            "s."
+            "new System."]
+            "s."        
+
+    [<Test>]
+    [<Category("QueryExpressions")>]
+    member this.``QueryExpression.CtrlSpaceSmokeTest0``() = 
+           this.VerifyCtrlSpaceListContainAllAtStartOfMarker(
+              fileContents = """
+                module BasicTest
+                let x = si(*Marker*)""" ,
+              marker = "(*Marker*)",
+              list = ["sin"],
+              addtlRefAssy=standard40AssemblyRefs )
+
+    [<Test>]
+    [<Category("QueryExpressions")>]
+    member this.``QueryExpression.CtrlSpaceSmokeTest0b``() = 
+           this.VerifyCtrlSpaceListContainAllAtStartOfMarker(
+              fileContents = """
+                module BasicTest
+                let x = qu(*Marker*)""" ,
+              marker = "(*Marker*)",
+              list = ["query"],
+              addtlRefAssy=standard40AssemblyRefs   )
+
+    [<Test>]
+    [<Category("QueryExpressions")>]
+    member this.``QueryExpression.CtrlSpaceSmokeTest1``() = 
+           this.VerifyCtrlSpaceListContainAllAtStartOfMarker(
+              fileContents = """
+                module BasicTest
+                let x = query { for x in [1;2;3] do sel(*Marker*)""" ,
+              marker = "(*Marker*)",
+              list = ["select"],
+              addtlRefAssy=standard40AssemblyRefs  )
+
+    [<Test>]
+    [<Category("QueryExpressions")>]
+    member this.``QueryExpression.CtrlSpaceSmokeTest1b``() = 
+           this.VerifyCtrlSpaceListContainAllAtStartOfMarker(
+              fileContents = """
+                module BasicTest
+                let x = query { for x in [1;2;3] do (*Marker*)""" ,
+              marker = "(*Marker*)",
+              list = ["select"],
+              addtlRefAssy=standard40AssemblyRefs  )
+
+
+
+    [<Test>]
+    [<Category("QueryExpressions")>]
+    member this.``QueryExpression.CtrlSpaceSmokeTest2``() = 
+           this.VerifyCtrlSpaceListContainAllAtStartOfMarker(
+              fileContents = """
+                module BasicTest
+                let x = query { for x in [1;2;3] do sel(*Marker*) }""" ,
+              marker = "(*Marker*)",
+              list = ["select"],
+              addtlRefAssy=standard40AssemblyRefs  )
+
+
+    [<Test>]
+    [<Category("QueryExpressions")>]
+    member this.``QueryExpression.CtrlSpaceSmokeTest3``() = 
+           this.VerifyCtrlSpaceListContainAllAtStartOfMarker(
+              fileContents = """
+                module BasicTest
+                let x = query { for xxxxxx in [1;2;3] do xxx(*Marker*)""" ,
+              marker = "(*Marker*)",
+              list = ["xxxxxx"],
+              addtlRefAssy=standard40AssemblyRefs  )
+
+
+    [<Test>]
+    [<Category("QueryExpressions")>]
+    member this.``QueryExpression.CtrlSpaceSmokeTest3b``() = 
+           this.VerifyCtrlSpaceListContainAllAtStartOfMarker(
+              fileContents = """
+                module BasicTest
+                let x = seq { for xxxxxx in [1;2;3] do xxx(*Marker*)""" ,
+              marker = "(*Marker*)",
+              list = ["xxxxxx"],
+              addtlRefAssy=standard40AssemblyRefs  )
+
+
+
+    [<Test>]
+    [<Category("QueryExpressions")>]
+    member this.``QueryExpression.CtrlSpaceSmokeTest3c``() = 
+           this.VerifyCtrlSpaceListContainAllAtStartOfMarker(
+              fileContents = """
+                module BasicTest
+                let x = async { for xxxxxx in [1;2;3] do xxx(*Marker*)""" ,
+              marker = "(*Marker*)",
+              list = ["xxxxxx"],
+              addtlRefAssy=standard40AssemblyRefs  )
+
+
+    [<Test>]
+    [<Category("QueryExpressions")>]
+    member this.``AsyncExpression.CtrlSpaceSmokeTest3d``() = 
+           this.VerifyCtrlSpaceListContainAllAtStartOfMarker(
+              fileContents = """
+                module BasicTest
+                let x = async { for xxxxxx in [1;2;3] do xxx(*Marker*) }""" ,
+              marker = "(*Marker*)",
+              list = ["xxxxxx"],
+              addtlRefAssy=standard40AssemblyRefs  )
+
+
+    member this.QueryExpressionFileExamples() = 
+           [ """
+                module BasicTest
+                let x = query { for x in [1;2;3] do (*TYPING*)"""
+             """
+                module BasicTest
+                let x = query { for x in [1;2;3] do (*TYPING*) }""" 
+             """
+                module BasicTest
+                let x = query { for x in [1;2;3] do 
+                                (*TYPING*)""" 
+             """
+                module BasicTest
+                let x = query { for x in [1;2;3] do 
+                                if x > 3 then 
+                                (*TYPING*)""" 
+             """
+                module BasicTest
+                let x = query { for x in [1;2;3] do 
+                                where (x > 3)
+                                (*TYPING*)""" 
+             """
+                module BasicTest
+                let x = query { for x in [1;2;3] do 
+                                sortBy x 
+                                (*TYPING*)""" 
+             """
+                module BasicTest
+                let x = query { for x in [1;2;3] do 
+                                (*TYPING*)
+                                sortBy x """ 
+             """
+                module BasicTest
+                let x = query { for x in [1;2;3] do 
+                                let y = x + 1
+                                (*TYPING*)""" ]
+
+    [<Test>]
+    /// This is the case where at (*TYPING*) we first type 1...N-1 characters of the target custom operation and then invoke the completion list, and we check that the completion list contains the custom operation
+    [<Category("QueryExpressions")>]
+    [<Category("TakesMoreThanFifteenSeconds")>]
+    member this.``QueryExpression.CtrlSpaceSystematic1``() = 
+       let rec strictPrefixes (s:string) = seq { if s.Length > 1 then let s = s.[0..s.Length-2] in yield s; yield! strictPrefixes s}
+       for customOperation in ["select";"skip";"contains";"groupJoin"] do
+        printfn " Running systematic tests looking for completion of '%s' at multiple locations"  customOperation
+        for idText in strictPrefixes customOperation do
+         for i,fileContents in this.QueryExpressionFileExamples() |> List.mapi (fun i x -> (i,x)) do
+           let fileContents = fileContents.Replace("(*TYPING*)",idText+"(*Marker*)")
+           try 
+               this.VerifyCtrlSpaceListContainAllAtStartOfMarker(
+                  fileContents = fileContents,
+                  marker = "(*Marker*)",
+                  list = [customOperation],
+                  addtlRefAssy=standard40AssemblyRefs )
+           with _ -> 
+               printfn "FAILURE: customOperation = %s, idText = %s, fileContents <<<%s>>>" customOperation idText fileContents
+               reraise()
+
+
+    member this.WordByWordSystematicTestWithSpecificExpectations(prefix, suffixes, lines, variations, knownFailures:list<_>) = 
+
+        let knownFailuresDict = set knownFailures
+        printfn "Building systematic tests, excluding %d known failures" knownFailures.Length  
+        let tests = 
+            [ for (suffixName,suffixText) in suffixes  do
+                for builderName in variations do
+                  for (lineName, line, checks) in lines builderName do 
+                    for check in checks do
+                      let expectedToFail = knownFailuresDict.Contains (lineName, suffixName, builderName, check)
+                      yield (lineName, suffixName, suffixText, builderName, line, check, expectedToFail) ]
+
+        let unexpectedSuccesses = ResizeArray<_>()
+        let successes = ResizeArray<_>()
+        let failures = ResizeArray<_>()
+        printfn "Running %d systematic tests.... Failure will be printed if it occurs..."  tests.Length
+        for (lineName, suffixName, suffixText, builderName, fileContents, check, expectedToFail) in tests do
+            if successes.Count % 50 = 0 then 
+                printfn "Making progress, run %d so far..." successes.Count
+            let fileContents = prefix + fileContents + suffixText
+            try 
+                match check with 
+                | QuickInfoExpected(where,expected) -> 
+                      let where = where.[0..where.Length-2] // chop a character off to get in the middle of the text
+                      this.AssertQuickInfoContainsAtEndOfMarker(fileContents,where,expected,addtlRefAssy=standard40AssemblyRefs )
+                | AutoCompleteExpected(where,expected) -> 
+                      this.VerifyCtrlSpaceListContainAllAtStartOfMarker(fileContents,where,[expected],addtlRefAssy=standard40AssemblyRefs )
+                | DotCompleteExpected(where,expected) -> 
+                      this.VerifyDotCompListContainAllAtStartOfMarker(fileContents,where,[expected], addtlRefAssy=standard40AssemblyRefs)
+                if not expectedToFail then
+                    successes.Add(lineName,suffixName,builderName,check)
+                else
+                    unexpectedSuccesses.Add(lineName,suffixName,builderName,check)
+            with _ ->  
+                if not expectedToFail then
+                    printfn " FAILURE on systematic test: (\"%s\", \"%s\", \"%s\", %A) " lineName suffixName builderName check
+                    printfn "\n\nfileContents = <<<%s>>>" fileContents
+                    failures.Add(lineName,suffixName,builderName,check)
+
+        let nFail = failures.Count
+        let nSuccess = successes.Count
+        printfn "%d TESTS, %d SUCCESS, %d FAILURE, %%%2.2f success rate" (nSuccess+nFail) successes.Count nFail  (float nSuccess / float (nSuccess+nFail) * 100.0)
+
+        if failures.Count <> 0 then 
+            printfn "EXTRA OBSERVED FAILURES:  "
+            printfn "["
+            for (lineName,suffixName,builderName,check) in failures do
+                printfn "   (\"%s\", \"%s\", \"%s\", %A) " lineName suffixName builderName check
+            printfn "]"
+             
+        if unexpectedSuccesses.Count <> 0 then 
+            printfn "EXTRA OBSERVED SUCCESSES:  "
+            printfn "["
+            for (lineName,suffixName,builderName,check) in unexpectedSuccesses do
+                printfn "   (\"%s\", \"%s\", \"%s\", %A) " lineName suffixName builderName check
+            printfn "]"
+
+        if failures.Count <> 0 || unexpectedSuccesses.Count <> 0 then 
+            raise <| new Exception("there were unexpected results, see console output for details")
+
+
+
+    [<Test>]
+    [<Category("QueryExpressions")>]
+    [<Category("TakesMoreThanFifteenSeconds")>]
+    member this.``QueryExpressions.QueryAndSequenceExpressionWithForYieldLoopSystematic``() = 
+
+        let prefix =  """
+module Test
+let aaaaaa = [| "1" |]
+"""
+        let suffixes = 
+          [ "Empty",                                ""; 
+            "ClosingBrace",                         " }"; 
+            "ClosingBrace,NextDefinition",        " } \nlet nextDefinition () = 1\n"; 
+            "NoClosingBrace,NextDefinition",      " \nlet nextDefinition () = 1\n"; 
+            "NoClosingBrace,NextTypeDefinition",  " \ntype NextDefinition() = member x.P = 1\n" 
+          ] 
+        let lines b = 
+          [ "L1",  "let v = " + b +  " { "                                                              , []
+            "L2",  "let v = " + b +  " { for "                                                          , []
+            "L3",  "let v = " + b +  " { for bbbb "                                                     , [QI "for bbbb" "val bbbb"]
+            "L4",  "let v = " + b +  " { for bbbb in (*C*)"                                             , [QI "for bbbb" "val bbbb"; AC "(*C*)" "aaaaaa" ]
+            "L5",  "let v = " + b +  " { for bbbb in [ (*C*) "                                          , [QI "for bbbb" "val bbbb"; AC "(*C*)" "aaaaaa" ]
+            "L6",  "let v = " + b +  " { for bbbb in [ aaa(*C*) "                                       , [QI "for bbbb" "val bbbb"; AC "(*C*)" "aaaaaa" ]
+            "L7",  "let v = " + b +  " { for bbbb in [ aaaaaa(*D1*)"                                    , [QI "for bbbb" "val bbbb"; QI "aaaaaa" "val aaaaaa"; DC "(*D1*)" "Length" ]
+            "L8",  "let v = " + b +  " { for bbbb in [ aaaaaa(*D1*) ] "                                 , [QI "for bbbb" "val bbbb"; QI "aaaaaa" "val aaaaaa"; DC "(*D1*)" "Length" ]
+            "L9",  "let v = " + b +  " { for bbbb in [ aaaaaa(*D1*) ] do (*C*)"                         , [QI "for bbbb" "val bbbb"; QI "aaaaaa" "val aaaaaa"; AC "(*C*)" (if b = "query" then "select" else "sin"); DC "(*D1*)" "Length" ]
+            "L10", "let v = " + b +  " { for bbbb in [ aaaaaa(*D1*) ] do yield (*C*) "                  , [QI "for bbbb" "val bbbb"; QI "aaaaaa" "val aaaaaa"; AC "(*C*)" "aaaaaa"; AC "(*C*)" "bbbb" ; DC "(*D1*)" "Length" ] 
+            "L11", "let v = " + b +  " { for bbbb in [ aaaaaa(*D1*) ] do yield bb(*C*) "                , [QI "for bbbb" "val bbbb"; QI "aaaaaa" "val aaaaaa"; AC "(*C*)" "bbbb" ; DC "(*D1*)" "Length" ]
+            "L12", "let v = " + b +  " { for bbbb in [ aaaaaa(*D1*) ] do yield bbbb(*D2*) "             , [QI "for bbbb" "val bbbb"; QI "aaaaaa" "val aaaaaa"; QI "yield bbbb" "val bbbb"; DC "(*D1*)" "Length" ; DC "(*D2*)" "Length" ]
+            "L13", "let v = " + b +  " { for bbbb in [ aaaaaa(*D1*) ] do yield bbbb(*D2*) + (*C*)"      , [QI "for bbbb" "val bbbb"; QI "aaaaaa" "val aaaaaa"; QI "yield bbbb" "val bbbb"; AC "(*C*)" "aaaaaa"; AC "(*C*)" "bbbb" ; DC "(*D1*)" "Length" ; DC "(*D2*)" "Length" ] 
+            "L14", "let v = " + b +  " { for bbbb in [ aaaaaa(*D1*) ] do yield bbbb(*D2*) + bb(*C*)"    , [QI "for bbbb" "val bbbb"; QI "aaaaaa" "val aaaaaa"; QI "yield bbbb" "val bbbb"; AC "(*C*)" "bbbb" ; DC "(*D1*)" "Length" ; DC "(*D2*)" "Length" ]
+            "L15", "let v = " + b +  " { for bbbb in [ aaaaaa(*D1*) ] do yield bbbb(*D2*) + bbbb(*D3*)" , [QI "for bbbb" "val bbbb"; QI "aaaaaa" "val aaaaaa"; QI "yield bbbb" "val bbbb"; QI "+ bbbb" "val bbbb"; DC "(*D3*)" "Length" ] ]
+
+
+        let knownFailures = 
+
+            [
+                ("L10", "Empty", "seq", AutoCompleteExpected ("(*C*)","bbbb")) 
+                ("L10", "Empty", "query", AutoCompleteExpected ("(*C*)","bbbb")) 
+                ("L10", "ClosingBrace", "query", AutoCompleteExpected ("(*C*)","bbbb")) 
+                ("L10", "ClosingBrace,NextDefinition", "query", AutoCompleteExpected ("(*C*)","bbbb")) 
+                ("L3", "NoClosingBrace,NextDefinition", "seq", QuickInfoExpected ("for bbbb","val bbbb")) 
+                ("L6", "NoClosingBrace,NextDefinition", "seq", QuickInfoExpected ("for bbbb","val bbbb")) 
+                ("L6", "NoClosingBrace,NextDefinition", "seq", AutoCompleteExpected ("(*C*)","aaaaaa")) 
+                ("L7", "NoClosingBrace,NextDefinition", "seq", QuickInfoExpected ("for bbbb","val bbbb")) 
+                ("L7", "NoClosingBrace,NextDefinition", "seq", QuickInfoExpected ("aaaaaa","val aaaaaa")) 
+                ("L7", "NoClosingBrace,NextDefinition", "seq", DotCompleteExpected ("(*D1*)","Length")) 
+                ("L3", "NoClosingBrace,NextDefinition", "query", QuickInfoExpected ("for bbbb","val bbbb")) 
+                ("L6", "NoClosingBrace,NextDefinition", "query", QuickInfoExpected ("for bbbb","val bbbb")) 
+                ("L6", "NoClosingBrace,NextDefinition", "query", AutoCompleteExpected ("(*C*)","aaaaaa")) 
+                ("L7", "NoClosingBrace,NextDefinition", "query", QuickInfoExpected ("for bbbb","val bbbb")) 
+                ("L7", "NoClosingBrace,NextDefinition", "query", QuickInfoExpected ("aaaaaa","val aaaaaa")) 
+                ("L7", "NoClosingBrace,NextDefinition", "query", DotCompleteExpected ("(*D1*)","Length")) 
+                ("L10", "NoClosingBrace,NextDefinition", "seq", AutoCompleteExpected ("(*C*)","bbbb")) 
+                ("L10", "NoClosingBrace,NextTypeDefinition", "seq", AutoCompleteExpected ("(*C*)","bbbb")) 
+                ("L10", "NoClosingBrace,NextDefinition", "query", AutoCompleteExpected ("(*C*)","bbbb")) 
+                ("L10", "NoClosingBrace,NextTypeDefinition", "query", AutoCompleteExpected ("(*C*)","bbbb")) 
+            ]
+
+        this.WordByWordSystematicTestWithSpecificExpectations(prefix, suffixes, lines, ["seq";"query"], knownFailures) 
+             
+
+    [<Test>]
+    [<Category("QueryExpressions")>]
+    [<Category("TakesMoreThanFifteenSeconds")>]
+    /// Incrementally enter a seq{ .. while ...} loop and check for availability of intellisense etc.
+    member this.``SequenceExpressions.SequenceExprWithWhileLoopSystematic``() = 
+
+        let prefix =  """
+module Test
+let abbbbc = [| 1 |]
+let aaaaaa = 0
+"""
+        let suffixes = 
+          [ "Empty",                                ""; 
+            "ClosingBrace",                         " }"; 
+            "ClosingBrace,NextDefinition",        " } \nlet nextDefinition () = 1\n"; 
+            "NoClosingBrace,NextDefinition",      " \nlet nextDefinition () = 1\n"; 
+            "NoClosingBrace,NextTypeDefinition",  " \ntype NextDefinition() = member x.P = 1\n" 
+          ] 
+        let lines b = 
+          [ "L1",  "let f()  = seq { while abb(*C*)"                                     , [AC "(*C*)" "abbbbc"]
+            "L2",  "let f()  = seq { while abbbbc(*D1*)"                                 , [QI "while abbbbc" "val abbbbc"; DC "(*D1*)" "Length"]
+            "L3",  "let f()  = seq { while abbbbc(*D1*) do (*C*)"                        , [QI "while abbbbc" "val abbbbc"; DC "(*D1*)" "Length"; AC "(*C*)" "abbbbc"]
+            "L4",  "let f()  = seq { while abbbbc(*D1*) do abb(*C*)"                     , [QI "while abbbbc" "val abbbbc"; DC "(*D1*)" "Length"; AC "(*C*)" "abbbbc"]
+            "L5",  "let f()  = seq { while abbbbc(*D1*) do abbbbc(*D2*)"                 , [QI "while abbbbc" "val abbbbc"; DC "(*D1*)" "Length"; QI "do abbbbc" "val abbbbc"; DC "(*D2*)" "Length"; ]
+            "L6",  "let f()  = seq { while abbbbc(*D1*) do abbbbc.[(*C*)"                , [QI "while abbbbc" "val abbbbc"; DC "(*D1*)" "Length"; QI "do abbbbc" "val abbbbc"; AC "(*C*)" "abbbbc"; AC "(*C*)" "aaaaaa"; ]
+            "L7",  "let f()  = seq { while abbbbc(*D1*) do abbbbc.[aaa(*C*)"             , [QI "while abbbbc" "val abbbbc"; DC "(*D1*)" "Length"; QI "do abbbbc" "val abbbbc"; AC "(*C*)" "aaaaaa"; ]
+            "L7a", "let f()  = seq { while abbbbc(*D1*) do abbbbc.[aaa(*C*)]"            , [QI "while abbbbc" "val abbbbc"; DC "(*D1*)" "Length"; QI "do abbbbc" "val abbbbc"; AC "(*C*)" "aaaaaa"; ]
+            "L7b", "let f()  = seq { while abbbbc(*D1*) do abbbbc.[aaa(*C*)] <- "        , [QI "while abbbbc" "val abbbbc"; DC "(*D1*)" "Length"; QI "do abbbbc" "val abbbbc"; AC "(*C*)" "aaaaaa"; ]
+            "L7c", "let f()  = seq { while abbbbc(*D1*) do abbbbc.[aaa(*C*)] <- 1"       , [QI "while abbbbc" "val abbbbc"; DC "(*D1*)" "Length"; QI "do abbbbc" "val abbbbc"; AC "(*C*)" "aaaaaa"; ]
+            "L7d", "let f()  = seq { while abbbbc(*D1*) do abbbbc.[ (*C*) ] <- 1"        , [QI "while abbbbc" "val abbbbc"; DC "(*D1*)" "Length"; QI "do abbbbc" "val abbbbc"; AC "(*C*)" "aaaaaa"; ]
+            "L8",  "let f()  = seq { while abbbbc(*D1*) do abbbbc.[aaaaaa]"              , [QI "while abbbbc" "val abbbbc"; DC "(*D1*)" "Length"; QI "do abbbbc" "val abbbbc"; ]
+            "L9",  "let f()  = seq { while abbbbc(*D1*) do abbbbc.[aaaaaa] <- (*C*)"     , [QI "while abbbbc" "val abbbbc"; DC "(*D1*)" "Length"; QI "do abbbbc" "val abbbbc"; AC "(*C*)" "abbbbc"; AC "(*C*)" "aaaaaa"; ]
+            "L10", "let f()  = seq { while abbbbc(*D1*) do abbbbc.[aaaaaa] <- aaa(*C*)"  , [QI "while abbbbc" "val abbbbc"; DC "(*D1*)" "Length"; QI "do abbbbc" "val abbbbc"; AC "(*C*)" "aaaaaa"; ] ]
+            
+        let knownFailures = 
+            [
+            ]
+
+        this.WordByWordSystematicTestWithSpecificExpectations(prefix, suffixes, lines, [""], knownFailures) 
+             
+
+    [<Test>]
+    [<Category("QueryExpressions")>]
+    [<Category("TakesMoreThanFifteenSeconds")>]
+    /// Incrementally enter query with a 'join' and check for availability of quick info, auto completion and dot completion 
+    member this.``QueryAndOtherExpressions.WordByWordSystematicJoinQueryOnSingleLine``() = 
+
+        let prefix =  """
+module Test
+let abbbbc = [| 1 |]
+let aaaaaa = 0
+"""
+        let suffixes = 
+          [ "Empty",                                ""; 
+            "ClosingBrace",                         " }"; 
+            "ClosingBrace,NextDefinition",        " } \nlet nextDefinition () = 1\n"; 
+            "NoClosingBrace,NextDefinition",      " \nlet nextDefinition () = 1\n"; 
+            "NoClosingBrace,NextTypeDefinition",  " \ntype NextDefinition() = member x.P = 1\n" 
+          ] 
+        let lines b = 
+          [ "L1",  "let x = query { for bbbb in abbbbc(*D0*) do join "  ,                                     [QI "for bbbb" "val bbbb"; QI "in abbbbc" "val abbbbc"; DC "(*D0*)" "Length"; QI "join" "join"]
+            "L2",  "let x = query { for bbbb in abbbbc(*D0*) do join cccc "  ,                           [QI "for bbbb" "val bbbb"; QI "in abbbbc" "val abbbbc"; DC "(*D0*)" "Length"; QI "join" "join"]
+            "L2a", "let x = query { for bbbb in abbbbc(*D0*) do join cccc )"  ,                          [QI "for bbbb" "val bbbb"; QI "in abbbbc" "val abbbbc"; DC "(*D0*)" "Length"; QI "join" "join"]
+            "L3",  "let x = query { for bbbb in abbbbc(*D0*) do join cccc in "  ,                        [QI "for bbbb" "val bbbb"; QI "in abbbbc" "val abbbbc"; DC "(*D0*)" "Length"; QI "join" "join"]
+            "L3a", "let x = query { for bbbb in abbbbc(*D0*) do join cccc in )"  ,                       [QI "for bbbb" "val bbbb"; QI "in abbbbc" "val abbbbc"; DC "(*D0*)" "Length"; QI "join" "join"]
+            "L4",  "let x = query { for bbbb in abbbbc(*D0*) do join cccc in abbb(*C*)"  ,               [QI "for bbbb" "val bbbb"; QI "in abbbbc" "val abbbbc"; DC "(*D0*)" "Length";QI "join" "join"; AC "(*C*)" "abbbbc"]
+            "L4a", "let x = query { for bbbb in abbbbc(*D0*) do join cccc in abbb(*C*) )"  ,             [QI "for bbbb" "val bbbb"; QI "in abbbbc" "val abbbbc"; DC "(*D0*)" "Length";QI "join" "join"; AC "(*C*)" "abbbbc"]
+            "L5",  "let x = query { for bbbb in abbbbc(*D0*) do join cccc in abbbbc(*D1*)"  ,            [QI "for bbbb" "val bbbb"; QI "in abbbbc" "val abbbbc"; DC "(*D0*)" "Length"; QI "join" "join"; DC "(*D1*)" "Length"]
+            "L5a", "let x = query { for bbbb in abbbbc(*D0*) do join cccc in abbbbc(*D1*) )"  ,          [QI "for bbbb" "val bbbb"; QI "in abbbbc" "val abbbbc"; DC "(*D0*)" "Length"; QI "join" "join"; DC "(*D1*)" "Length"]
+            "L6",  "let x = query { for bbbb in abbbbc(*D0*) do join cccc in abbbbc(*D1*) on "  ,        [QI "for bbbb" "val bbbb"; QI "in abbbbc" "val abbbbc"; DC "(*D0*)" "Length"; QI "join" "join"; DC "(*D1*)" "Length"]
+            "L6a", "let x = query { for bbbb in abbbbc(*D0*) do join cccc in abbbbc(*D1*) on )"  ,       [QI "for bbbb" "val bbbb"; QI "in abbbbc" "val abbbbc"; DC "(*D0*)" "Length"; QI "join" "join"; DC "(*D1*)" "Length"]
+            "L6b", "let x = query { for bbbb in abbbbc(*D0*) do join cccc in abbbbc(*D1*) on (bb(*C*)"  , [QI "for bbbb" "val bbbb"; QI "in abbbbc" "val abbbbc"; DC "(*D0*)" "Length"; QI "join" "join"; DC "(*D1*)" "Length"; AC "(*C*)" "bbbb"]
+            "L7",  "let x = query { for bbbb in abbbbc(*D0*) do join cccc in abbbbc(*D1*) on (bbbb"  ,    [QI "for bbbb" "val bbbb"; QI "in abbbbc" "val abbbbc"; DC "(*D0*)" "Length"; QI "join" "join"; DC "(*D1*)" "Length"]
+            "L7a", "let x = query { for bbbb in abbbbc(*D0*) do join cccc in abbbbc(*D1*) on (bbbb )"  ,  [QI "for bbbb" "val bbbb"; QI "in abbbbc" "val abbbbc"; DC "(*D0*)" "Length"; QI "join" "join"; DC "(*D1*)" "Length"]
+            "L8",  "let x = query { for bbbb in abbbbc(*D0*) do join cccc in abbbbc(*D1*) on (bbbb = "  , [QI "for bbbb" "val bbbb"; QI "in abbbbc" "val abbbbc"; DC "(*D0*)" "Length"; QI "join" "join"; DC "(*D1*)" "Length"]
+            "L8a", "let x = query { for bbbb in abbbbc(*D0*) do join cccc in abbbbc(*D1*) on (bbbb = )"  , [QI "for bbbb" "val bbbb"; QI "in abbbbc" "val abbbbc"; DC "(*D0*)" "Length"; QI "join" "join"; DC "(*D1*)" "Length"]
+            "L8b", "let x = query { for bbbb in abbbbc(*D0*) do join cccc in abbbbc(*D1*) on (bbbb = cc(*C*)"  ,                                              [QI "for bbbb" "val bbbb"; QI "in abbbbc" "val abbbbc"; DC "(*D0*)" "Length"; QI "join" "join"; DC "(*D1*)" "Length"; AC "(*C*)" "cccc"]
+            "L9",  "let x = query { for bbbb in abbbbc(*D0*) do join cccc in abbbbc(*D1*) on (bbbb(*D11*) = cccc(*D12*)"  ,                                   [QI "for bbbb" "val bbbb"; QI "in abbbbc" "val abbbbc"; DC "(*D0*)" "Length"; QI "join" "join"; DC "(*D1*)" "Length"; DC "(*D11*)" "CompareTo"; DC "(*D12*)" "CompareTo"]
+            "L10", "let x = query { for bbbb in abbbbc(*D0*) do join cccc in abbbbc(*D1*) on (bbbb(*D11*) = cccc(*D12*))"  ,                                  [QI "for bbbb" "val bbbb"; QI "in abbbbc" "val abbbbc"; DC "(*D0*)" "Length"; QI "join" "join"; DC "(*D1*)" "Length"; DC "(*D11*)" "CompareTo"; DC "(*D12*)" "CompareTo"]
+            "L11", "let x = query { for bbbb in abbbbc(*D0*) do join cccc in abbbbc(*D1*) on (bbbb(*D11*) = cccc(*D12*)); "  ,                                [QI "for bbbb" "val bbbb"; QI "in abbbbc" "val abbbbc"; DC "(*D0*)" "Length"; QI "join" "join"; DC "(*D1*)" "Length"; DC "(*D11*)" "CompareTo"; DC "(*D12*)" "CompareTo"]
+            "L12", "let x = query { for bbbb in abbbbc(*D0*) do join cccc in abbbbc(*D1*) on (bbbb(*D11*) = cccc(*D12*)); select"  ,                          [QI "for bbbb" "val bbbb"; QI "in abbbbc" "val abbbbc"; DC "(*D0*)" "Length"; QI "join" "join"; DC "(*D1*)" "Length"; DC "(*D11*)" "CompareTo"; DC "(*D12*)" "CompareTo"]
+            "L13", "let x = query { for bbbb in abbbbc(*D0*) do join cccc in abbbbc(*D1*) on (bbbb(*D11*) = cccc(*D12*)); select (bb(*C*)"  ,                 [QI "for bbbb" "val bbbb"; QI "in abbbbc" "val abbbbc"; DC "(*D0*)" "Length"; QI "join" "join"; DC "(*D1*)" "Length"; DC "(*D11*)" "CompareTo"; DC "(*D12*)" "CompareTo"]
+            "L14", "let x = query { for bbbb in abbbbc(*D0*) do join cccc in abbbbc(*D1*) on (bbbb(*D11*) = cccc(*D12*)); select (bbbb(*D2*)"  ,              [QI "for bbbb" "val bbbb"; QI "in abbbbc" "val abbbbc"; DC "(*D0*)" "Length"; QI "join" "join"; DC "(*D1*)" "Length"; DC "(*D2*)" "CompareTo"; DC "(*D11*)" "CompareTo"; DC "(*D12*)" "CompareTo"]
+            "L15", "let x = query { for bbbb in abbbbc(*D0*) do join cccc in abbbbc(*D1*) on (bbbb(*D11*) = cccc(*D12*)); select (bbbb(*D2*), "  ,            [QI "for bbbb" "val bbbb"; QI "in abbbbc" "val abbbbc"; DC "(*D0*)" "Length"; QI "join" "join"; DC "(*D1*)" "Length"; DC "(*D2*)" "CompareTo"; DC "(*D11*)" "CompareTo"; DC "(*D12*)" "CompareTo"]
+            "L16", "let x = query { for bbbb in abbbbc(*D0*) do join cccc in abbbbc(*D1*) on (bbbb(*D11*) = cccc(*D12*)); select (bbbb(*D2*), cc(*C*)"  ,     [QI "for bbbb" "val bbbb"; QI "in abbbbc" "val abbbbc"; DC "(*D0*)" "Length"; QI "join" "join"; DC "(*D1*)" "Length"; DC "(*D2*)" "CompareTo"; AC "(*C*)" "cccc"; DC "(*D11*)" "CompareTo"; DC "(*D12*)" "CompareTo"]
+            "L17", "let x = query { for bbbb in abbbbc(*D0*) do join cccc in abbbbc(*D1*) on (bbbb(*D11*) = cccc(*D12*)); select (bbbb(*D2*), cccc(*D3*)"  ,  [QI "for bbbb" "val bbbb"; QI "in abbbbc" "val abbbbc"; DC "(*D0*)" "Length"; QI "join" "join"; DC "(*D1*)" "Length"; DC "(*D2*)" "CompareTo"; DC "(*D3*)"  "CompareTo"; QI "(bbbb" "val bbbb"; QI ", cccc" "val cccc"; DC "(*D11*)" "CompareTo"; DC "(*D12*)" "CompareTo" ]
+            "L18", "let x = query { for bbbb in abbbbc(*D0*) do join cccc in abbbbc(*D1*) on (bbbb(*D11*) = cccc(*D12*)); select (bbbb(*D2*), cccc(*D3*))"  , [QI "for bbbb" "val bbbb"; QI "in abbbbc" "val abbbbc"; DC "(*D0*)" "Length"; QI "join" "join"; DC "(*D1*)" "Length"; DC "(*D2*)" "CompareTo"; DC "(*D3*)" "CompareTo"; QI "(bbbb" "val bbbb"; QI ", cccc" "val cccc"; DC "(*D11*)" "CompareTo"; DC "(*D12*)" "CompareTo" ] ]
+            
+        let knownFailures = 
+             [
+               //("L2", "NoClosingBrace,NextDefinition", "", QuickInfoExpected ("for bbbb","val bbbb")) 
+               //("L2", "NoClosingBrace,NextDefinition", "", QuickInfoExpected ("in abbbbc","val abbbbc")) 
+               //("L2", "NoClosingBrace,NextDefinition", "", DotCompleteExpected ("(*D0*)","Length")) 
+               //("L2", "NoClosingBrace,NextDefinition", "", QuickInfoExpected ("join","join")) 
+            ]
+
+        this.WordByWordSystematicTestWithSpecificExpectations(prefix, suffixes, lines, [""], knownFailures) 
+             
+
+    [<Test>]
+    /// This is a sanity check that the multiple-line case is much the same as the single-line cae
+    [<Category("QueryExpressions")>]
+    [<Category("TakesMoreThanFifteenSeconds")>]
+    member this.``QueryAndOtherExpressions.WordByWordSystematicJoinQueryOnMultipleLine``() = 
+
+        let prefix =  """
+module Test
+let abbbbc = [| 1 |]
+let aaaaaa = 0
+"""
+        let suffixes = 
+          [ "Empty",                                ""; 
+            "ClosingBrace",                         " }"; 
+            "ClosingBrace,NextDefinition",        " } \nlet nextDefinition () = 1\n"; 
+            "NoClosingBrace,NextDefinition",      " \nlet nextDefinition () = 1\n"; 
+            "NoClosingBrace,NextTypeDefinition",  " \ntype NextDefinition() = member x.P = 1\n" 
+          ] 
+        let lines b = 
+          [ "L1",  """
+let x = query { for bbbb in abbbbc(*D0*) do 
+join 
+"""                                                 ,  [QI "for bbbb" "val bbbb"; QI "in abbbbc" "val abbbbc"; DC "(*D0*)" "Length"; QI "join" "join"]
+            "L2",  """
+let x = query { for bbbb in abbbbc(*D0*) do 
+                join cccc 
+"""                                                 , [QI "for bbbb" "val bbbb"; QI "in abbbbc" "val abbbbc"; DC "(*D0*)" "Length"; QI "join" "join"]
+
+            "L2a", """
+let x = query { for bbbb in abbbbc(*D0*) do 
+                join cccc )
+"""                                                 , [QI "for bbbb" "val bbbb"; QI "in abbbbc" "val abbbbc"; DC "(*D0*)" "Length"; QI "join" "join"]
+
+            "L3",  """
+let x = query { for bbbb in abbbbc(*D0*) do 
+                join cccc in 
+"""                                                 , [QI "for bbbb" "val bbbb"; QI "in abbbbc" "val abbbbc"; DC "(*D0*)" "Length"; QI "join" "join"]
+
+            "L3a", """
+let x = query { for bbbb in abbbbc(*D0*) do 
+                join cccc in )
+"""                                                 , [QI "for bbbb" "val bbbb"; QI "in abbbbc" "val abbbbc"; DC "(*D0*)" "Length"; QI "join" "join"]
+
+            "L4",  """
+let x = query { for bbbb in abbbbc(*D0*) do 
+                join cccc in abbb(*C*)
+"""                                                 , [QI "for bbbb" "val bbbb"; QI "in abbbbc" "val abbbbc"; DC "(*D0*)" "Length";QI "join" "join"; AC "(*C*)" "abbbbc"]
+
+            "L4a", """
+let x = query { for bbbb in abbbbc(*D0*) do 
+                join cccc in abbb(*C*) )
+"""                                                 , [QI "for bbbb" "val bbbb"; QI "in abbbbc" "val abbbbc"; DC "(*D0*)" "Length";QI "join" "join"; AC "(*C*)" "abbbbc"]
+
+            "L5",  """
+let x = query { for bbbb in abbbbc(*D0*) do 
+                join cccc in abbbbc(*D1*)
+"""                                                 , [QI "for bbbb" "val bbbb"; QI "in abbbbc" "val abbbbc"; DC "(*D0*)" "Length"; QI "join" "join"; DC "(*D1*)" "Length"]
+
+            "L5a", """
+let x = query { for bbbb in abbbbc(*D0*) do 
+                join cccc in abbbbc(*D1*) )
+"""                                                ,  [QI "for bbbb" "val bbbb"; QI "in abbbbc" "val abbbbc"; DC "(*D0*)" "Length"; QI "join" "join"; DC "(*D1*)" "Length"]
+
+            "L6",  """
+let x = query { for bbbb in abbbbc(*D0*) do 
+                join cccc in abbbbc(*D1*) on 
+"""                                                ,  [QI "for bbbb" "val bbbb"; QI "in abbbbc" "val abbbbc"; DC "(*D0*)" "Length"; QI "join" "join"; DC "(*D1*)" "Length"]
+
+            "L6a", """
+let x = query { for bbbb in abbbbc(*D0*) do 
+                join cccc in abbbbc(*D1*) on )
+"""                                                ,  [QI "for bbbb" "val bbbb"; QI "in abbbbc" "val abbbbc"; DC "(*D0*)" "Length"; QI "join" "join"; DC "(*D1*)" "Length"]
+            "L6b", """
+let x = query { for bbbb in abbbbc(*D0*) do 
+                join cccc in abbbbc(*D1*) on (bb(*C*)
+"""                                                , [QI "for bbbb" "val bbbb"; QI "in abbbbc" "val abbbbc"; DC "(*D0*)" "Length"; QI "join" "join"; DC "(*D1*)" "Length"; AC "(*C*)" "bbbb"]
+            "L7",  """
+let x = query { for bbbb in abbbbc(*D0*) do 
+                join cccc in abbbbc(*D1*) on (bbbb
+"""                                                ,    [QI "for bbbb" "val bbbb"; QI "in abbbbc" "val abbbbc"; DC "(*D0*)" "Length"; QI "join" "join"; DC "(*D1*)" "Length"]
+            "L7a", """
+let x = query { for bbbb in abbbbc(*D0*) do 
+                join cccc in abbbbc(*D1*) on (bbbb )
+"""                                                ,  [QI "for bbbb" "val bbbb"; QI "in abbbbc" "val abbbbc"; DC "(*D0*)" "Length"; QI "join" "join"; DC "(*D1*)" "Length"]
+            "L8",  """
+let x = query { for bbbb in abbbbc(*D0*) do 
+                join cccc in abbbbc(*D1*) on (bbbb = 
+"""                                                , [QI "for bbbb" "val bbbb"; QI "in abbbbc" "val abbbbc"; DC "(*D0*)" "Length"; QI "join" "join"; DC "(*D1*)" "Length"]
+            "L8a", """
+let x = query { for bbbb in abbbbc(*D0*) do 
+                join cccc in abbbbc(*D1*) on (bbbb = )
+"""                                                , [QI "for bbbb" "val bbbb"; QI "in abbbbc" "val abbbbc"; DC "(*D0*)" "Length"; QI "join" "join"; DC "(*D1*)" "Length"]
+            "L8b", """
+let x = query { for bbbb in abbbbc(*D0*) do 
+                join cccc in abbbbc(*D1*) on (bbbb = cc(*C*)
+"""                                                , [QI "for bbbb" "val bbbb"; QI "in abbbbc" "val abbbbc"; DC "(*D0*)" "Length"; QI "join" "join"; DC "(*D1*)" "Length"; AC "(*C*)" "cccc"]
+            "L9",  """
+let x = query { for bbbb in abbbbc(*D0*) do 
+                join cccc in abbbbc(*D1*) on (bbbb(*D11*) = cccc(*D12*)
+"""                                                , [QI "for bbbb" "val bbbb"; QI "in abbbbc" "val abbbbc"; DC "(*D0*)" "Length"; QI "join" "join"; DC "(*D1*)" "Length"; DC "(*D11*)" "CompareTo"; DC "(*D12*)" "CompareTo"]
+            "L10", """
+let x = query { for bbbb in abbbbc(*D0*) do 
+                join cccc in abbbbc(*D1*) on (bbbb(*D11*) = cccc(*D12*))
+"""                                               ,  [QI "for bbbb" "val bbbb"; QI "in abbbbc" "val abbbbc"; DC "(*D0*)" "Length"; QI "join" "join"; DC "(*D1*)" "Length"; DC "(*D11*)" "CompareTo"; DC "(*D12*)" "CompareTo"]
+            "L11", """
+let x = query { for bbbb in abbbbc(*D0*) do 
+                join cccc in abbbbc(*D1*) on (bbbb(*D11*) = cccc(*D12*)); 
+"""                                               , [QI "for bbbb" "val bbbb"; QI "in abbbbc" "val abbbbc"; DC "(*D0*)" "Length"; QI "join" "join"; DC "(*D1*)" "Length"; DC "(*D11*)" "CompareTo"; DC "(*D12*)" "CompareTo"]
+            "L12", """
+let x = query { for bbbb in abbbbc(*D0*) do 
+                join cccc in abbbbc(*D1*) on (bbbb(*D11*) = cccc(*D12*)); select
+"""                                               ,  [QI "for bbbb" "val bbbb"; QI "in abbbbc" "val abbbbc"; DC "(*D0*)" "Length"; QI "join" "join"; DC "(*D1*)" "Length"; DC "(*D11*)" "CompareTo"; DC "(*D12*)" "CompareTo"]
+            "L13", """
+let x = query { for bbbb in abbbbc(*D0*) do 
+                join cccc in abbbbc(*D1*) on (bbbb(*D11*) = cccc(*D12*)); select (bb(*C*)
+"""                                               ,  [QI "for bbbb" "val bbbb"; QI "in abbbbc" "val abbbbc"; DC "(*D0*)" "Length"; QI "join" "join"; DC "(*D1*)" "Length"; DC "(*D11*)" "CompareTo"; DC "(*D12*)" "CompareTo"]
+            "L14", """
+let x = query { for bbbb in abbbbc(*D0*) do 
+                join cccc in abbbbc(*D1*) on (bbbb(*D11*) = cccc(*D12*)); select (bbbb(*D2*)
+"""                                              , [QI "for bbbb" "val bbbb"; QI "in abbbbc" "val abbbbc"; DC "(*D0*)" "Length"; QI "join" "join"; DC "(*D1*)" "Length"; DC "(*D2*)" "CompareTo"; DC "(*D11*)" "CompareTo"; DC "(*D12*)" "CompareTo"]
+            "L15", """
+let x = query { for bbbb in abbbbc(*D0*) do 
+                join cccc in abbbbc(*D1*) on (bbbb(*D11*) = cccc(*D12*)); select (bbbb(*D2*), 
+"""                                               , [QI "for bbbb" "val bbbb"; QI "in abbbbc" "val abbbbc"; DC "(*D0*)" "Length"; QI "join" "join"; DC "(*D1*)" "Length"; DC "(*D2*)" "CompareTo"; DC "(*D11*)" "CompareTo"; DC "(*D12*)" "CompareTo"]
+            "L16", """
+let x = query { for bbbb in abbbbc(*D0*) do 
+                join cccc in abbbbc(*D1*) on (bbbb(*D11*) = cccc(*D12*)); select (bbbb(*D2*), cc(*C*)
+"""                                               ,  [QI "for bbbb" "val bbbb"; QI "in abbbbc" "val abbbbc"; DC "(*D0*)" "Length"; QI "join" "join"; DC "(*D1*)" "Length"; DC "(*D2*)" "CompareTo"; AC "(*C*)" "cccc"; DC "(*D11*)" "CompareTo"; DC "(*D12*)" "CompareTo"]
+            "L17", """
+let x = query { for bbbb in abbbbc(*D0*) do 
+                join cccc in abbbbc(*D1*) on (bbbb(*D11*) = cccc(*D12*)); select (bbbb(*D2*), cccc(*D3*)
+"""                                               ,  [QI "for bbbb" "val bbbb"; QI "in abbbbc" "val abbbbc"; DC "(*D0*)" "Length"; QI "join" "join"; DC "(*D1*)" "Length"; DC "(*D2*)" "CompareTo"; DC "(*D3*)"  "CompareTo"; QI "(bbbb" "val bbbb"; QI ", cccc" "val cccc"; DC "(*D11*)" "CompareTo"; DC "(*D12*)" "CompareTo" ]
+            "L18", """
+let x = query { for bbbb in abbbbc(*D0*) do 
+                join cccc in abbbbc(*D1*) on (bbbb(*D11*) = cccc(*D12*)); select (bbbb(*D2*), cccc(*D3*))
+"""                                              , [QI "for bbbb" "val bbbb"; QI "in abbbbc" "val abbbbc"; DC "(*D0*)" "Length"; QI "join" "join"; DC "(*D1*)" "Length"; DC "(*D2*)" "CompareTo"; DC "(*D3*)" "CompareTo"; QI "(bbbb" "val bbbb"; QI ", cccc" "val cccc"; DC "(*D11*)" "CompareTo"; DC "(*D12*)" "CompareTo" ] ]
+
+        let knownFailures = 
+
+              [
+                 //("L2", "NoClosingBrace,NextDefinition", "", QuickInfoExpected ("for bbbb","val bbbb")) 
+                 //("L2", "NoClosingBrace,NextDefinition", "", QuickInfoExpected ("in abbbbc","val abbbbc")) 
+                 //("L2", "NoClosingBrace,NextDefinition", "", DotCompleteExpected ("(*D0*)","Length")) 
+                 //("L2", "NoClosingBrace,NextDefinition", "", QuickInfoExpected ("join","join")) 
+              ]
+
+
+        this.WordByWordSystematicTestWithSpecificExpectations(prefix, suffixes, lines, [""], knownFailures) 
+
+    [<Test>]
+    /// This is the case where (*TYPING*) nothing has been typed yet and we invoke the completion list
+    /// This is a known failure right now for some of the example files above.
+    member this.``QueryExpression.CtrlSpaceSystematic2``() = 
+         for fileContents in this.QueryExpressionFileExamples() do
+           
+           try 
+               this.VerifyCtrlSpaceListContainAllAtStartOfMarker(
+                  fileContents = fileContents,
+                  marker = "(*TYPING*)",
+                  list = customOperations,
+                  addtlRefAssy=standard40AssemblyRefs )
+           with _ -> 
+               printfn "FAILURE on systematic test: fileContents = <<<%s>>>" fileContents
+               reraise()
+
+
+
+    (* Various parser recovery test cases -------------------------------------------------- *)
+
+//*****************Helper Function*****************
+    member public this.AutoCompleteRecoveryTest(source : list<string>, marker, expected) =
+        let (_, _, file) = this.CreateSingleFileProject(source)
+        MoveCursorToEndOfMarker(file, marker)
+        let completions = time1 CtrlSpaceCompleteAtCursor file "Time of first autocomplete."
+        AssertCompListContainsAll(completions, expected)
+            
+    [<Test>]
+    member public this.``Parameter.CommonCase.Bug2884``() =     
+        this.AutoCompleteRecoveryTest
+            ([ 
+               "type T1(aaa1) ="
+               "  do (" ], "do (", [ "aaa1" ])
+
+    [<Test>]
+    member public this.``Parameter.SubsequentLet.Bug2884``() =     
+        this.AutoCompleteRecoveryTest
+            ([ 
+               "type T1(aaa1) ="
+               "  do ("
+               "let a = 0" ], "do (", [ "aaa1" ]) 
+                      
+    [<Test>]
+    member public this.``Parameter.SubsequentMember.Bug2884``() =     
+        this.AutoCompleteRecoveryTest
+            ([ 
+               "type T1(aaa1) ="
+               "  member x.Foo(aaa2) = "
+               "    do ("
+               "  member x.Bar = 0" ], "do (", [ "aaa1"; "aaa2" ])        
+
+    [<Test>]
+    member public this.``Parameter.System.DateTime.Bug2884``() =     
+        this.AutoCompleteRecoveryTest
+            ([ 
+               "type T1(aaa1) ="
+               "  member x.Foo(aaa2) = "
+               "    let dt = new System.DateTime(" ], "Time(", [ "aaa1"; "aaa2" ])        
+
+    [<Test>]
+    member public this.``Parameter.DirectAfterDefined.Bug2884``() =     
+        this.AutoCompleteRecoveryTest
+            ([  
+               "if true then"
+               "  let aaa1 = 0"
+               "  (" ], "(", [ "aaa1" ])
+
+    [<Test>]
+    member public this.``NotShowInfo.LetBinding.Bug3602``() =  
+        this.VerifyAutoCompListIsEmptyAtEndOfMarker(
+            fileContents = "let s. = \"Hello world\"
+                            ()",
+            marker = "let s.")   
+    
+    [<Test>]
+    member public this.``NotShowInfo.FunctionParameter.Bug3602``() = 
+        this.VerifyAutoCompListIsEmptyAtEndOfMarker(
+            fileContents = "let foo s. = s + \"Hello world\"
+                            ()",
+            marker = "let foo s.") 
+                                               
+    [<Test>]
+    member public this.``NotShowInfo.ClassMemberDeclA.Bug3602``() =     
+        this.TestCompletionNotShowingWhenFastUpdate
+            [ 
+              "type Foo() ="
+              "    member this.Func (x, y) = ()"
+              "    member (*marker*) this.Prop = 10"
+              "()" ]
+            [  
+              "type Foo() ="
+              "    member this.Func (x, y) = ()"
+              "    member (*marker*) this."
+              "()" ]        
+            "(*marker*) this."
+                                            
+    // Another test case for the same thing - this goes through a different code path
+    [<Test>]
+    member public this.``NotShowInfo.ClassMemberDeclB.Bug3602``() =     
+        this.TestCompletionNotShowingWhenFastUpdate
+            [  
+              "type Foo() ="
+              "    member this.Func (x, y) = ()"
+              "    //   marker$" // <- trick to move the cursor to the right location before source replacement
+              "()" ] 
+            [  
+              "type Foo() ="
+              "    member this.Func (x, y) = ()"
+              "    member this."
+              "()" ]        
+            "marker$"
+
+    [<Test>]
+    member public this.``ComputationExpression.LetBang``() =     
+        AssertAutoCompleteContainsNoCoffeeBreak
+            ["let http(url:string) = "
+             "  async { "
+             "    let rnd = new System.Random()"
+             "    let! rsp = rnd.N" ]
+            "rsp = rnd."
+            ["Next"]
+            []   
+
+   (* Tests for autocomplete -------------------------------------------------------------- *)
+                     
+    member public this.TestGenericAutoComplete(line, expected) =
+        let code = 
+         [  "type GT<'a> ="
+            "  static member P = 12"
+            "  static member Q = 13"
+            "type GT2 ="
+            "  static member R = 12"
+            "  static member S = 13"
+            "type D = | DD"
+            "let td = typeof<D>"
+            "let f i = typeof<D>"
+            ""; line ]
+        let (_, _, file) = this.CreateSingleFileProject(code)
+        let gpatcc = GlobalParseAndTypeCheckCounter.StartNew(this.VS)
+        MoveCursorToEndOfMarker(file, line)
+        let completions = AutoCompleteAtCursor file
+        AssertCompListContainsAll(completions, expected)
+        gpatcc.AssertExactly(0,0)
+
+    [<Test>]
+    member public this.``Generics.Typeof``() =        
+        this.TestGenericAutoComplete ("let _ = typeof<int>.", [ "Assembly"; "AssemblyQualifiedName"; (* ... *) ])
+
+    [<Test>]
+    member public this.``Generics.NonGenericTypeMembers``() =        
+        this.TestGenericAutoComplete ("let _ = GT2.", [ "R"; "S" ])
+
+    [<Test>]
+    member public this.``Generics.GenericTypeMembers``() =        
+        this.TestGenericAutoComplete ("let _ = GT<int>.", [ "P"; "Q" ])
+
+   //[<Test>]    // keep disabled unless trying to prove that UnhandledExceptionHandler is working
+    member public this.EnsureThatUnhandledExceptionsCauseAnAssert() =
+        // Do something that causes LanguageService to load
+        AssertAutoCompleteContains 
+          [ 
+            "type FooBuilder() ="
+            "   member x.Return(a) = new System.Random()"
+            "let foo = FooBuilder()"
+            "(foo { return 0 })." ]
+          "})."       // marker
+          [ "Next" ] // should contain
+          [ "GetEnumerator" ] // should not contain
+        // kaboom
+        let t = new System.Threading.Thread(new System.Threading.ThreadStart(fun () -> failwith "foo"))
+        t.Start()
+        System.Threading.Thread.Sleep(1000)
+
+    [<Test>]
+    member public this.``DotBetweenParens.Bug175360.Case1``() =
+        AssertAutoCompleteContains 
+            [
+                "let a = 10."
+                "(a :> System.IConvertible).(null) |> ignore" ]
+            "ible)."
+            [ "ToDecimal" ] // should contain
+            [] // should not contain
+
+    [<Test>]
+    member public this.``DotBetweenParens.Bug175360.Case2``() =
+        AssertAutoCompleteContains 
+            [ "[| 1 |].(0)" ]
+            "|]."
+            [ "Clone" ] // should contain
+            [] // should not contain
+
+    [<Test>]
+    [<Ignore("Not worth fixing right now")>]
+    member public this.``GenericType.Self.Bug69673_1.01``() =    
+        AssertCtrlSpaceCompleteContains
+            ["type Base(o:obj) = class end"
+             "type Foo() as this ="
+             "    inherit Base(this) // this"
+             "    let o = this // this ok"
+             "    do this.Bar() // this ok, dotting ok"
+             "    member this.Bar() = ()" ]
+            "Base(th"
+            ["this"]
+            []
+
+    [<Test>]
+    member public this.``GenericType.Self.Bug69673_1.02``() =    
+        AssertCtrlSpaceCompleteContains
+            ["type Base(o:obj) = class end"
+             "type Foo() as this ="
+             "    inherit Base(this) // this"
+             "    let o = this // this ok"
+             "    do this.Bar() // this ok, dotting ok"
+             "    member this.Bar() = ()" ]
+            "o = th"
+            ["this"]
+            []
+
+    [<Test>]
+    member public this.``GenericType.Self.Bug69673_1.03``() =    
+        AssertCtrlSpaceCompleteContains
+            ["type Base(o:obj) = class end"
+             "type Foo() as this ="
+             "    inherit Base(this) // this"
+             "    let o = this // this ok"
+             "    do this.Bar() // this ok, dotting ok"
+             "    member this.Bar() = ()" ]
+            "do th"
+            ["this"]
+            []
+
+    [<Test>]
+    member public this.``GenericType.Self.Bug69673_1.04``() =    
+        AssertAutoCompleteContains
+            ["type Base(o:obj) = class end"
+             "type Foo() as this ="
+             "    inherit Base(this) // this"
+             "    let o = this // this ok"
+             "    do this.Bar() // this ok, dotting ok"
+             "    member this.Bar() = ()" ]
+            "do this."
+            ["Bar"]
+            []
+
+    [<Test>]
+    [<Ignore("this is not worth fixing")>]
+    member public this.``GenericType.Self.Bug69673_2.1``() =  
+        AssertAutoCompleteContains
+            ["type Base(o:obj) = class end"
+             "type Food() as this ="
+             "    class"
+             "    inherit Base(this) // this"
+             "    do"
+             "        this |> ignore // this (only repros with explicit class/end)"
+             "    end" ]  
+            "Base(th"  
+            ["this"] 
+            []       
+            
+    [<Test>]
+    [<Ignore("this is not worth fixing")>]
+    member public this.``GenericType.Self.Bug69673_2.2``() =  
+        AssertAutoCompleteContains
+            ["type Base(o:obj) = class end"
+             "type Food() as this ="
+             "    class"
+             "    inherit Base(this) // this"
+             "    do"
+             "        this |> ignore // this (only repros with explicit class/end)"
+             "    end" ]  
+            "     th"  
+            ["this"] 
+            []                       
+
+    [<Test>]
+    member public this.``UnitMeasure.Bug78932_1``() =        
+        AssertAutoCompleteContains 
+          [ @"
+            module M1 =
+               [<Measure>] type Kg
+ 
+            module M2 = 
+                let f = 1<M1. >  // <- type . between M1 and ' >'   => works" ]
+          "M1."       // marker
+          [ "Kg" ] // should contain
+          [  ] // should not contain
+
+    [<Test>]
+    member public this.``UnitMeasure.Bug78932_2``() =        
+        // Note: in this case, pressing '.' does not automatically pop up a completion list in VS, but ctrl-space does get the right list
+        // This is just like how
+        //     let y = true.>"trueSuffix"   // no popup on dot, but ctrl-space brings up list with ToString that is legal completion
+        // works, the issue is ".>" is seen as an operator and not a dot-for-completion.
+        AssertAutoCompleteContains 
+          [ @"
+            module M1 =
+               [<Measure>] type Kg
+ 
+            module M2 = 
+                let f = 1<M1.>  // <- type . between M1 and '>'     => no popup intellisense" ]
+          "M1."       // marker
+          [ "Kg" ] // should contain
+          [ ] // should not contain
+
+    [<Test>]
+    member public this.``Array.AfterOperator...Bug65732_A``() =        
+        AssertAutoCompleteContains 
+          [ "let r = [1 .. System.Int32.MaxValue]" ]
+          "System."       // marker
+          [ "Int32" ] // should contain
+          [ "abs" ] // should not contain (from top level)
+
+    [<Test>]
+    member public this.``Array.AfterOperator...Bug65732_B``() =        
+        AssertCtrlSpaceCompleteContains 
+          [ "let r = [System.Int32.MaxValue..42]" ]
+          ".."       // marker
+          [ "abs" ] // should contain (top level)
+          [ "CompareTo" ] // should not contain (from Int32)
+
+    // Verify the auto completion after the close-parentheses,
+    // there should be auto completion
+    [<Test>]
+    member public this.``Array.AfterParentheses.Bug175360``() =        
+        AssertAutoCompleteContainsNoCoffeeBreak 
+          [ "let a = 10."
+            "let r = (a :> System.IConvertible).(null)" ]
+          "IConvertible)."       // marker
+          [ "ToDecimal" ] // should contain (top level)
+          [ ] // should not contain 
+
+    [<Test>]
+    member public this.``Identifier.FuzzyDefiend.Bug67133``() =  
+        AssertAutoCompleteContainsNoCoffeeBreak
+          [ "let gDateTime (arr: System.DateTime[]) ="
+            "    arr.[0]." ]
+          "arr.[0]."
+          ["AddDays"]
+          []
+
+    [<Test>]
+    member public this.``Identifier.FuzzyDefiend.Bug67133.Negative``() =        
+        let code = [ "let gDateTime (arr: DateTime[]) ="  // Note: no 'open System', so DateTime is unknown
+                     "    arr.[0]." ]
+        let (_, _, file) = this.CreateSingleFileProject(code)
+        TakeCoffeeBreak(this.VS)
+        let gpatcc = GlobalParseAndTypeCheckCounter.StartNew(this.VS)
+        MoveCursorToEndOfMarker(file, "arr.[0].")
+        let completions = AutoCompleteAtCursor file
+        AssertCompListContainsExactly(completions, []) // we don't want any completions on <expr>. when <expr> has unknown type due to errors
+        // (In particular, we don't want the "didn't find any completions, so just show top-level entities like 'abs' here" logic to kick in.)
+
+    [<Test>]
+    member public this.``Class.Property.Bug69150_A``() =        
+        AssertCtrlSpaceCompleteContains 
+          [ "type ClassType(x : int) ="
+            "    member this.Value = x"
+            "let z = (new ClassType(23)).Value" ]
+          "))."       // marker
+          [ "Value" ] // should contain
+          [ "CompareTo" ] // should not contain (from Int32)
+
+    [<Test>]
+    member public this.``Class.Property.Bug69150_B``() =        
+        AssertCtrlSpaceCompleteContains 
+          [ "type ClassType(x : int) ="
+            "    member this.Value = x"
+            "let z = ClassType(23).Value" ]
+          "3)."       // marker
+          [ "Value" ] // should contain
+          [ "CompareTo" ] // should not contain (from Int32)
+
+    [<Test>]
+    member public this.``Class.Property.Bug69150_C``() =        
+        AssertCtrlSpaceCompleteContains 
+          [ "type ClassType(x : int) ="
+            "    member this.Value = x"
+            "let f x = new ClassType(x)"
+            "let z = f(23).Value" ]
+          "3)."       // marker
+          [ "Value" ] // should contain
+          [ "CompareTo" ] // should not contain (from Int32)
+
+    [<Test>]
+    member public this.``Class.Property.Bug69150_D``() =        
+        AssertCtrlSpaceCompleteContains 
+          [ "type ClassType(x : int) ="
+            "    member this.Value = x"
+            "let z = ClassType(23).Value" ]
+          "3).V"       // marker
+          [ "Value" ] // should contain
+          [ "VolatileFieldAttribute" ] // should not contain (from top-level)
+
+    [<Test>]
+    member public this.``Class.Property.Bug69150_E``() =        
+        AssertCtrlSpaceCompleteContains 
+          [ "type ClassType(x : int) ="
+            "    member this.Value = x"
+            "let z = ClassType(23)   .   Value" ]
+          "3)   . "       // marker
+          [ "Value" ] // should contain
+          [ "VolatileFieldAttribute" ] // should not contain (from top-level)
+
+    [<Test>]
+    member public this.``AssignmentToProperty.Bug231283``() =        
+        AssertCtrlSpaceCompleteContains 
+            ["""
+                type Foo() =
+                    member val Bar = 0 with get,set
+
+                let f = new Foo()
+                f.Bar <-
+                    let xyz = 42 (*Mark*)
+                    xyz """]
+            "42 "
+            [ "AbstractClassAttribute" ] // top-level completions
+            [ "Bar" ] // not stuff from the lhs of assignment
+
+    [<Test>]
+    member public this.``Dot.AfterOperator.Bug69159``() =        
+        AssertAutoCompleteContains 
+          [ "let x1 = [|0..1..10|]." ]
+          "]."       // marker
+          [ "Length" ] // should contain (array)
+          [ "abs" ] // should not contain (top-level)
+
+    [<Test>]
+    member public this.``Residues1``() =        
+        AssertCtrlSpaceCompleteContains 
+          [ "System   .   Int32   .   M" ]
+          "M"       // marker
+          [ "MaxValue"; "MinValue" ] // should contain
+          [ "MailboxProcessor"; "Map" ] // should not contain (top-level)
+
+    [<Test>]
+    member public this.``Residues2``() =        
+        AssertCtrlSpaceCompleteContains 
+          [ "let x = 42"
+            "x   .  C" ]
+          "C"       // marker
+          [ "CompareTo" ] // should contain (Int32)
+          [ "CLIEventAttribute"; "Checked"; "Choice" ] // should not contain (top-level)
+
+    [<Test>]
+    member public this.``Residues3``() =        
+        AssertCtrlSpaceCompleteContains 
+          [ "let x = 42"
+            "x   .  " ]
+          ".  "       // marker
+          [ "CompareTo" ] // should contain (Int32)
+          [ "CLIEventAttribute"; "Checked"; "Choice" ] // should not contain (top-level)
+
+    [<Test>]
+    member public this.``Residues4``() =        
+        AssertCtrlSpaceCompleteContains 
+          [ "let x = 42"
+            "id(x)   .  C" ]
+          "C"       // marker
+          [ "CompareTo" ] // should contain (Int32)
+          [ "CLIEventAttribute"; "Checked"; "Choice" ] // should not contain (top-level)
+
+    [<Test>]
+    member public this.``CtrlSpaceInWhiteSpace.Bug133112``() =        
+        AssertCtrlSpaceCompleteContains 
+          [ """
+            type Foo = 
+                static member A = 1
+                static member B = 2
+ 
+            printfn "%d %d" Foo.A  """ ]
+          "Foo.A "       // marker
+          [ "AbstractClassAttribute" ] // should contain (top-level)
+          [ "A"; "B" ] // should not contain (Foo)
+
+    [<Test>]
+    member public this.``Residues5``() =        
+        AssertCtrlSpaceCompleteContains 
+          [ "let x = 42"
+            "id(x)   .  " ]
+          ".  "       // marker
+          [ "CompareTo" ] // should contain (Int32)
+          [ "CLIEventAttribute"; "Checked"; "Choice" ] // should not contain (top-level)
+    [<Test>]
+    member public this.``CompletionInDifferentEnvs1``() = 
+        AssertCtrlSpaceCompleteContains
+            ["let f1 num ="
+             "    let rec completeword d ="
+             "        d + d"
+             "(**)comple"]
+            "(**)comple" // marker
+            ["completeword"] // should contain
+            [""]
+
+    [<Test>]
+    member public this.``CompletionInDifferentEnvs2``() = 
+        AssertCtrlSpaceCompleteContains
+            ["let aaa = 1"
+             "let aab = 2"
+             "(aa"
+             "let aac = 3"]
+             "(aa"
+            ["aaa"; "aab"]
+            ["aac"] 
+
+    [<Test>]
+    member public this.``CompletionInDifferentEnvs3``() = 
+        AssertCtrlSpaceCompleteContains
+            ["let mb1 = new MailboxProcessor<AsyncReplyChannel<int>>(fun inbox -> async { let! msg = inbox.Receive()"
+             "                                                                            do "]
+             "do "
+            ["msg"]
+            [] 
+
+    [<Test>]
+    member public this.``CompletionInDifferentEnvs4``() = 
+        AssertCtrlSpaceCompleteContains
+            ["async {"
+             "    let! x = i"
+             "    ("
+             "}"]
+             "("
+            ["x"]
+            [] 
+
+        AssertCtrlSpaceCompleteContains
+            ["let q = "
+             "    let a = 20"
+             "    let b = (fun i -> i) 40"
+             "    (("]
+             "(("
+            ["b"]
+            ["i"]
+
+
+            (**)
+    [<Test>]
+    member public this.``Bug229433.AfterMismatchedParensCauseWeirdParseTreeAndExceptionDuringTypecheck``() =        
+        AssertAutoCompleteContains [ """
+            type T() =
+                member this.Bar() = ()
+                member val X = "foo" with get,set
+                static member Id(x) = x
+ 
+            [1]
+            |> Seq.iter (fun x -> 
+                let user = x
+                ["foo"]
+                |> List.iter (fun m -> 
+                    let xyz = new T()
+                    xyz.X <- null
+                    T.Id((*here*)xyz.  // no intellisense here after .
+                    )
+                printfn ""
+                )  """ ]
+            "(*here*)xyz."
+            [ "Bar"; "X" ]
+            []
+
+    [<Test>]
+    member public this.``Bug130733.LongIdSet.CtrlSpace``() =        
+        AssertCtrlSpaceCompleteContains [ """
+            type C() =
+                member this.XX with get() = 4 and set(x) = ()
+
+            let c = C()
+            c.X <- 42""" ]
+            "c.X"
+            [ "XX" ]
+            []
+
+    [<Test>]
+    member public this.``Bug130733.LongIdSet.Dot``() =        
+        AssertAutoCompleteContains [ """
+            type C() =
+                member this.XX with get() = 4 and set(x) = ()
+
+            let c = C()
+            c.X <- 42""" ]
+            "c."
+            [ "XX" ]
+            []
+
+    [<Test>]
+    member public this.``Bug130733.ExprDotSet.CtrlSpace``() =        
+        AssertCtrlSpaceCompleteContains [ """
+            type C() =
+                member this.XX with get() = 4 and set(x) = ()
+
+            let f(x) = C()
+            f(0).X <- 42""" ]
+            ").X"
+            [ "XX" ]
+            []
+
+    [<Test>]
+    member public this.``Bug130733.ExprDotSet.Dot``() =        
+        AssertAutoCompleteContains [ """
+            type C() =
+                member this.XX with get() = 4 and set(x) = ()
+
+            let f(x) = C()
+            f(0).X <- 42""" ]
+            "(0)."
+            [ "XX" ]
+            []
+
+
+    [<Test>]
+    member public this.``Bug130733.Nested.LongIdSet.CtrlSpace``() =        
+        AssertCtrlSpaceCompleteContains [ """
+            type C() =
+                member this.XX with get() = 4 and set(x) = ()
+                member this.CC with get() = C()
+
+            let c = C()
+            c.CC.X <- 42""" ]
+            "CC.X"
+            [ "XX" ]
+            []
+
+    [<Test>]
+    member public this.``Bug130733.Nested.LongIdSet.Dot``() =        
+        AssertAutoCompleteContains [ """
+            type C() =
+                member this.XX with get() = 4 and set(x) = ()
+                member this.CC with get() = C()
+
+            let c = C()
+            c.CC.X <- 42""" ]
+            "c.CC."
+            [ "XX" ]
+            []
+
+    [<Test>]
+    member public this.``Bug130733.Nested.ExprDotSet.CtrlSpace``() =        
+        AssertCtrlSpaceCompleteContains [ """
+            type C() =
+                member this.XX with get() = 4 and set(x) = ()
+                member this.CC with get() = C()
+
+            let f(x) = C()
+            f(0).CC.X <- 42""" ]
+            "CC.X"
+            [ "XX" ]
+            []
+
+    [<Test>]
+    member public this.``Bug130733.Nested.ExprDotSet.Dot``() =        
+        AssertAutoCompleteContains [ """
+            type C() =
+                member this.XX with get() = 4 and set(x) = ()
+                member this.CC with get() = C()
+
+            let f(x) = C()
+            f(0).CC.X <- 42""" ]
+            "(0).CC."
+            [ "XX" ]
+            []
+
+    [<Test>]
+    member public this.``Bug130733.NamedIndexedPropertyGet.Dot``() =        
+        AssertAutoCompleteContains [ """
+            let str = "foo"
+            str.Chars(3).""" ]
+            ")."
+            [ "CompareTo" ] // char
+            []
+
+    [<Test>]
+    member public this.``Bug130733.NamedIndexedPropertyGet.CtrlSpace``() =        
+        AssertCtrlSpaceCompleteContains [ """
+            let str = "foo"
+            str.Chars(3).Co""" ]
+            ").Co"
+            [ "CompareTo" ] // char
+            []
+
+    [<Test>]
+    member public this.``Bug230533.NamedIndexedPropertySet.CtrlSpace.Case1``() =        
+        AssertCtrlSpaceCompleteContains [ """
+            type Foo() =
+                member x.MutableInstanceIndexer
+                    with get (i) = 0
+                    and  set (i) (v:string) = ()
+
+            let h() = new Foo()
+            (h()).MutableInstanceIndexer(0) <- "foo" """ ]
+            ")).Muta"
+            [ "MutableInstanceIndexer" ]
+            []
+
+    [<Test>]
+    member public this.``Bug230533.NamedIndexedPropertySet.CtrlSpace.Case2``() =        
+        AssertCtrlSpaceCompleteContains [ """
+            type Foo() =
+                member x.MutableInstanceIndexer
+                    with get (i) = 0
+                    and  set (i) (v:string) = ()
+            type Bar() =
+                member this.ZZZ = new Foo()
+
+            let g() = new Bar()
+            (g()).ZZZ.MutableInstanceIndexer(0) <- "blah"  """ ]
+            ")).ZZZ.Muta"
+            [ "MutableInstanceIndexer" ]
+            []
+
+    [<Test>]
+    member public this.``Bug230533.ExprDotSet.CtrlSpace.Case1``() =        
+        AssertCtrlSpaceCompleteContains [ """
+            type C() =
+                member this.XX with get() = 4 and set(x) = ()
+            type D() =
+                member this.CC = new C()
+            let f(x) = D()
+            f(0).CC.     <- 42 """ ]
+            "0).CC."
+            [ "XX" ]
+            []
+
+    [<Test>]
+    member public this.``Bug230533.ExprDotSet.CtrlSpace.Case2``() =        
+        AssertCtrlSpaceCompleteContains [ """
+            type C() =
+                member this.XX with get() = 4 and set(x) = ()
+            type D() =
+                member this.CC with get() = new C() and set(x) = ()
+            let f(x) = D()
+            f(0).CC.     <- 42 """ ]
+            "0).CC."
+            [ "XX" ]
+            []
+
+    [<Test>]
+    member public this.``Attribute.WhenAttachedToLet.Bug70080``() =        
+        this.AutoCompleteBug70080Helper @"
+                    open System
+                    [<Attr     // expect AttributeUsageAttribute from System namespace
+                    let f() = 4"
+
+    [<Test>]
+    member public this.``Attribute.WhenAttachedToType.Bug70080``() =        
+        this.AutoCompleteBug70080Helper @"
+                    open System
+                    [<Attr     // expect AttributeUsageAttribute from System namespace
+                    type MyAttr() = inherit Attribute()"
+
+    [<Test>]
+    member public this.``Attribute.WhenAttachedToNothing.Bug70080``() =        
+        this.AutoCompleteBug70080Helper @"
+                    open System
+                    [<Attr     // expect AttributeUsageAttribute from System namespace
+                    // nothing here"
+
+    [<Test>]
+    member public this.``Attribute.WhenAttachedToLetInNamespace.Bug70080``() =        
+        this.AutoCompleteBug70080Helper @"
+                    namespace Foo
+                    open System
+                    [<Attr     // expect AttributeUsageAttribute from System namespace
+                    let f() = 4"
+
+    [<Test>]
+    member public this.``Attribute.WhenAttachedToTypeInNamespace.Bug70080``() =        
+        this.AutoCompleteBug70080Helper @"
+                    namespace Foo
+                    open System
+                    [<Attr     // expect AttributeUsageAttribute from System namespace
+                    type MyAttr() = inherit Attribute()"
+
+    [<Test>]
+    member public this.``Attribute.WhenAttachedToNothingInNamespace.Bug70080``() =        
+        this.AutoCompleteBug70080Helper @"
+                    namespace Foo
+                    open System
+                    [<Attr     // expect AttributeUsageAttribute from System namespace
+                    // nothing here"
+
+    [<Test>]
+    member public this.``Attribute.WhenAttachedToModuleInNamespace.Bug70080``() =        
+        this.AutoCompleteBug70080Helper @"
+                    namespace Foo
+                    open System
+                    [<Attr     // expect AttributeUsageAttribute from System namespace
+                    module Foo = 
+                        let x = 42"
+
+    [<Test>]
+    member public this.``Attribute.WhenAttachedToModule.Bug70080``() =        
+        this.AutoCompleteBug70080Helper @"
+                    open System
+                    [<Attr     // expect AttributeUsageAttribute from System namespace
+                    module Foo = 
+                        let x = 42"
+
+    [<Test>]
+    member public this.``Identifer.InMatchStatemente.Bug72595``() =        
+        // in this bug, "match blah with let" caused the lexfilter to go awry, which made things hopeless for the parser, yielding no parse tree and thus no intellisense
+        AssertAutoCompleteContains 
+            [ @"
+                    type C() = 
+                        let someValue = ""abc""
+                        member __.M() = 
+                          let x = 1
+                          match someValue. with
+                            let x = 1
+                            match 1 with
+                            | _ -> 2
+    
+                    type D() = 
+                        member x.P = 1
+ 
+                    [<assembly:Microsoft.FSharp.Core.CompilerServices.TypeProviderAssembly(""Samples.DataStore.Freebase.DesignTime"")>]
+                    do()
+                " ]
+            "someValue." // marker
+            [ "Chars" ] // should contain
+            [ ] // should not contain
+
+    [<Test>]
+    member public this.``HandleInlineComments1``() =        
+        AssertAutoCompleteContains 
+          [ "let rrr = System  (* boo! *)  .  Int32  .  MaxValue" ]
+          ")  ."       // marker
+          [ "Int32"]
+          [ "abs" ] // should not contain (top-level)
+
+    [<Test>]
+    member public this.``HandleInlineComments2``() =    
+        AssertAutoCompleteContains 
+          [ "let rrr = System  (* boo! *)  .  Int32  .  MaxValue" ]
+          "2  ."       // marker
+          [ "MaxValue" ] // should contain 
+          [ "abs" ] // should not contain (top-level)
+
+    [<Test>]
+    member public this.``OpenNamespaceOrModule.CompletionOnlyContainsNamespaceOrModule.Case1``() =        
+        AssertAutoCompleteContains 
+            [ "open System." ]
+            "." // marker
+            [ "Collections" ] // should contain (namespace)
+            [ "Console" ] // should not contain (type)
+
+    [<Test>]
+    member public this.``OpenNamespaceOrModule.CompletionOnlyContainsNamespaceOrModule.Case2``() =        
+        AssertAutoCompleteContains 
+            [ "open Microsoft.FSharp.Collections.Array." ]
+            "Array." // marker
+            [ "Parallel" ] // should contain (module)
+            [ "map" ] // should not contain (let-bound value)
+
+    [<Test>]
+    member public this.``BY_DESIGN.CommonScenarioThatBegsTheQuestion.Bug73940``() =        
+        AssertAutoCompleteContains 
+            [ @"
+                    let r = 
+                        [""1""] 
+                           |> List.map (fun s -> s.     // user previous had e.g. '(fun s -> s)' here, but he erased after 's' to end-of-line and hit '.' e.g. to eventually type '.Substring(5))'
+                           |> List.filter (fun s -> s.Length > 5)  // parser recover assumes close paren is here, and type inference goes wacky-useless with such a parse
+                "]
+            "s." // marker
+            [ ] // should contain (ideally would be string)
+            [ "Chars" ] // should not contain (documenting the undesirable behavior, that this does not show up)
+
+    [<Test>]
+    member public this.``BY_DESIGN.ExplicitlyCloseTheParens.Bug73940``() =        
+        AssertAutoCompleteContains 
+            [ @"
+                    let g lam = 
+                        lam true |> printfn ""%b""
+                        sprintf ""%s""
+                    let r = 
+                        [""1""] 
+                           |> List.map (fun s -> s.  )   // user types close paren here to avoid paren mismatch
+                           |> g     // regardless of whatever is down here now, it won't affect the type of 's' above
+                "]
+            "s." // marker
+            [ "Chars" ] // should contain (string)
+            [ ] // should not contain
+
+    [<Test>]
+    member public this.``BY_DESIGN.MismatchedParenthesesAreHardToRecoverFromAndHereIsWhy.Bug73940``() =        
+        AssertAutoCompleteContains 
+            [ @"
+                    let g lam = 
+                        lam true |> printfn ""%b""
+                        sprintf ""%s""
+                    let r = 
+                        [""1""] 
+                           |> List.map (fun s -> s.   // it looks like s is a string here, but it's not!
+                           |> g     // parser recovers as though there is a right-paren here
+                "]
+            "s." // marker
+            [ "CompareTo" ] // should contain (bool)
+            [ "Chars" ] // should not contain (string)
+
+(*
+    [<Test>]
+    member public this.``AutoComplete.Bug72596_A``() =        
+        AssertAutoCompleteContains 
+          [ "type ClassType() ="
+            "    let foo = fo" ]  // is not 'let rec', foo should not be in scope yet, but showed up in completions
+          "= fo"       // marker
+          [ ] // should contain
+          [ "foo" ] // should not contain
+
+
+    [<Test>]
+    member public this.``AutoComplete.Bug72596_B``() =        
+        AssertAutoCompleteContains 
+          [ "let f() ="
+            "    let foo = fo" ]  // is not 'let rec', foo should not be in scope yet, but showed up in completions
+          "= fo"       // marker
+          [ ] // should contain
+          [ "foo" ] // should not contain
+*)
+
+    [<Test>]
+    member public this.``Expression.MultiLine.Bug66705``() =        
+        AssertAutoCompleteContains 
+          [ "let x = 4"
+            "let y = x.GetType()" 
+            "         .ToString()" ]  // "fluent" interface spanning multiple lines
+          "  ."       // marker
+          [ "ToString" ] // should contain
+          [ ] // should not contain
+
+    [<Test>]
+    [<Category("PerfCheck")>]
+    member public this.``Expressions.Computation``() =        
+        AssertAutoCompleteContains 
+          [
+            "type FooBuilder() ="
+            "   member x.Return(a) = new System.Random()"
+            "let foo = FooBuilder()"
+            "(foo { return 0 })." ]
+          "})."       // marker
+          [ "Next" ] // should contain
+          [ "GetEnumerator" ] // should not contain
+
+    [<Test>]
+    member public this.``Identifier.DefineByVal.InFsiFile.Bug882304_1``() =        
+        AutoCompleteInInterfaceFileContains
+          [
+            "module BasicTest"
+            "val z:int = 1"
+            "z."
+            ]
+          "z."       // marker
+          [ ] // should contain
+          [ "Equals" ] // should not contain
+
+    [<Test>]
+    member public this.``NameSpace.InFsiFile.Bug882304_2``() =        
+        AutoCompleteInInterfaceFileContains
+          [
+            "module BasicTest"
+            "open System."
+            ]
+          "System."       // marker
+          [ "Action"; // Delegate
+            "Activator"; // Class
+            "Collections"; // Subnamespace
+            "IConvertible"  // Interface 
+            ] // should contain
+          [  ] // should not contain
+
+    [<Test>]
+    member public this.``CLIEvents.DefinedInAssemblies.Bug787438``() =        
+        AssertAutoCompleteContains 
+          [ "let mb = new MailboxProcessor<int>(fun _ -> ())"
+            "mb." ]
+          "mb."       // marker
+          [ "Error" ] // should contain
+          [ "add_Error"; "remove_Error" ] // should not contain
+
+    [<Test>]
+    member public this.CLIEventsWithByRefArgs() =
+        AssertAutoCompleteContains 
+          [ "type MyDelegate = delegate of obj * string byref  -> unit"
+            "type mytype() = [<CLIEvent>] member this.myEvent = (new DelegateEvent<MyDelegate>()).Publish"
+            "let t = mytype()"
+            "t." ]
+          "t."       // marker
+          [ "add_myEvent"; "remove_myEvent" ] // should contain
+          [ "myEvent" ] // should not contain
+
+    [<Test>]
+    member public this.``Identifier.AfterParenthesis.Bug835276``() =        
+        AssertAutoCompleteContains 
+            [ "let f ( s : string ) ="
+              "   let x = 10 + s.Length"
+              "   for i in 1..10 do"
+              "     let ok = 10 + s.Length // dot here did work"
+              "     let y = 10 +(s." ]
+            "+(s." // marker
+          [ "Length" ] // should contain
+          [ ] // should not contain
+
+    [<Test>]
+    member public this.``Identifier.AfterParenthesis.Bug6484_1``() =        
+        AssertAutoCompleteContains 
+            [ "for x in 1..10 do"
+              "    printfn \"%s\" (x. " ]
+            "x." // marker
+          [ "CompareTo" ] // should contain (a method on the 'int' type)
+          [ ] // should not contain
+
+    [<Test>]
+    member public this.``Identifier.AfterParenthesis.Bug6484_2``() =        
+        AssertAutoCompleteContains 
+            [ "for x = 1 to 10 do"
+              "    printfn \"%s\" (x. " ]
+            "x." // marker
+          [ "CompareTo" ] // should contain (a method on the 'int' type)
+          [ ] // should not contain
+
+    [<Test>]
+    member public this.``Type.Indexers.Bug4898_1``() =        
+        AssertAutoCompleteContains 
+          [ 
+            "type Foo(len) ="
+            "    member this.Value = [1 .. len]"
+            "type Bar ="
+            "    static member ParamProp with get len = new Foo(len)"
+            "let n = Bar.ParamProp."]
+          "ar.ParamProp."       // marker
+          [ "ToString" ] // should contain
+          [ "Value" ] // should not contain      
+          
+    [<Test>]
+    member public this.``Type.Indexers.Bug4898_2``() =        
+        AssertAutoCompleteContains 
+          [ 
+            "type mytype() ="
+            "    let instanceArray2 = [|[| \"A\"; \"B\" |]; [| \"A\"; \"B\" |] |]"
+            "    let instanceArray = [| \"A\"; \"B\" |]"
+            "    member x.InstanceIndexer"
+            "        with get(idx) = instanceArray.[idx]"
+            "    member x.InstanceIndexer2"
+            "        with get(idx1,idx2) = instanceArray2.[idx1].[idx2]"
+            "let a = mytype()"
+            "a.InstanceIndexer2."]          
+
+          "a.InstanceIndexer2."       // marker
+          [ "ToString" ] // should contain
+          [ "Chars" ] // should not contain    
+                                             
+    [<Test>]
+    member public this.``Expressions.Sequence``() =        
+        AssertAutoCompleteContains 
+          [  
+            "(seq { yield 1 })." ]
+          "})."       // marker
+          [ "GetEnumerator" ] // should contain
+          [ ] // should not contain
+                      
+    [<Test>]
+    member public this.``LambdaExpression.WithoutClosing.Bug1346``() =        
+        AssertAutoCompleteContains 
+          [ 
+            "let p4 = "
+            "   let isPalindrome x = "
+            "       let chars = (string_of_int x).ToCharArray()"
+            "       let len = chars."
+            "       chars "
+            "       |> Array.mapi (fun i c ->" ]
+          "chars."       // marker
+          [ "Length" ] // should contain
+          [ ] // should not contain
+                      
+    [<Test>]
+    member public this.``LambdaExpression.WithoutClosing.Bug1346c``() =        
+        AssertAutoCompleteContains 
+          [ 
+            "let p4 = "
+            "   let isPalindrome x = "
+            "       let chars = (string_of_int x).ToCharArray()"
+            "       let len = chars."
+            "       chars "
+            "       |> Array.mapi (fun i c -> )" ]
+          "chars."       // marker
+          [ "Length" ] // should contain
+          [ ] // should not contain
+                  
+    [<Test>]
+    member public this.``LambdaExpression.WithoutClosing.Bug1346b``() =        
+        AssertAutoCompleteContains 
+          [ 
+            "let p4 = "
+            "   let isPalindrome x = "
+            "       let chars = (string_of_int x).ToCharArray()"
+            "       let len = chars."
+            "       chars "
+            "       |> Array.mapi (fun i c ->" 
+            "let p5 = 1" ]
+          "chars."       // marker
+          [ "Length" ] // should contain
+          [ ] // should not contain
+                                           
+    [<Test>]
+    member public this.``IncompleteStatement.If_A``() =        
+        AssertAutoCompleteContains 
+          [
+            "let x = \"1\""
+            "let test2 = if (x)." ]
+          "(x)."       // marker
+          [ "Contains" ] // should contain
+          [ ] // should not contain
+                                          
+    [<Test>]
+    member public this.``IncompleteStatemen.If_C``() =        
+        AssertAutoCompleteContains 
+          [  
+            "let x = \"1\""
+            "let test2 = if (x)." 
+            "let y = 2" ]
+          "(x)."       // marker
+          [ "Contains" ] // should contain
+          [ ] // should not contain
+                                         
+    [<Test>]
+    member public this.``IncompleteStatement.Try_A``() =        
+        AssertAutoCompleteContains 
+          [ 
+            "let x = \"1\""
+            "try (x)." ]
+          "(x)."       // marker
+          [ "Contains" ] // should contain
+          [ ] // should not contain
+                      
+    [<Test>]
+    member public this.``IncompleteStatement.Try_B``() =        
+        AssertAutoCompleteContains 
+          [
+            "let x = \"1\""
+            "try (x). finally ()" ]
+          "(x)."       // marker
+          [ "Contains" ] // should contain
+          [ ] // should not contain
+                      
+    [<Test>]
+    member public this.``IncompleteStatement.Try_C``() =        
+        AssertAutoCompleteContains 
+          [ 
+            "let x = \"1\""
+            "try (x). with e -> () " ]
+          "(x)."       // marker
+          [ "Contains" ] // should contain
+          [ ] // should not contain
+
+    [<Test>]
+    member public this.``IncompleteStatement.Try_D``() =        
+        AssertAutoCompleteContains 
+          [
+            "let x = \"1\""
+            "try (x)."
+            "let y = 2" ]
+          "(x)."       // marker
+          [ "Contains" ] // should contain
+          [ ] // should not contain
+                                        
+    [<Test>]
+    member public this.``IncompleteStatement.Match_A``() =        
+        AssertAutoCompleteContains 
+          [  
+            "let x = \"1\""
+            "let test2 = match (x)." ]
+          "(x)."       // marker
+          [ "Contains" ] // should contain
+          [ ] // should not contain
+
+    [<Test>]
+    member public this.``IncompleteStatement.Match_C``() =        
+        AssertAutoCompleteContains 
+          [ 
+            "let x = \"1\""
+            "let test2 = match (x)." 
+            "let y = 2"]
+          "(x)."       // marker
+          [ "Contains" ] // should contain
+          [ ] // should not contain
+
+    [<Test>]
+    member public this.``InDeclaration.Bug3176a``() =        
+        AssertCtrlSpaceCompleteContains 
+          [ "type T<'a> = { aaaa : 'a; bbbb : int } " ]
+          "aa"       // marker
+          [ "aaaa" ] // should contain
+          [ "bbbb" ] // should not contain
+
+    [<Test>]
+    member public this.``InDeclaration.Bug3176b``() =        
+        AssertCtrlSpaceCompleteContains 
+          [ "type T<'a> = { aaaa : 'a; bbbb : int } " ]
+          "bb"       // marker
+          [ "bbbb" ] // should contain
+          [ "aaaa" ] // should not contain
+
+    [<Test>]
+    member public this.``InDeclaration.Bug3176c``() =        
+        AssertCtrlSpaceCompleteContains 
+          [ "type C =";
+                      "  val aaaa : int" ]
+          "aa"        // move to marker
+          ["aaaa"] [] // should contain 'aaaa'
+
+    [<Test>]
+    member public this.``InDeclaration.Bug3176d``() =        
+        AssertCtrlSpaceCompleteContains 
+          [ "type DU<'a> =";
+                      "  | DULabel of 'a" ]
+          "DULab"        // move to marker
+          ["DULabel"] [] // should contain 'DULabel'
+          
+    [<Test>]
+    member public this.``IncompleteIfClause.Bug4594``() = 
+        AssertCtrlSpaceCompleteContains 
+          [ "let Bar(xyz) =";
+                      "  let hello = ";
+                      "    if x" ]
+          "if x"     // move to marker
+          ["xyz"] [] // should contain 'xyz'
+
+    [<Test>]
+    member public this.``Extensions.Bug5162``() =        
+        AssertCtrlSpaceCompleteContains 
+          [ "module Extensions ="
+            "    type System.Object with"
+            "        member x.P = 1"
+            "module M2 ="
+            "    let x = 1"
+            "    (*loc*)Ext" ]
+          "(*loc*)Ext"        // marker
+          [ "Extensions" ] [] // should contain
+          
+    (* Tests for various uses of ObsoleteAttribute ----------------------------------------- *)
+    (* Members marked with obsolete shouldn't be visible, but we should support              *)
+    (* dot completions on them                                                               *)
+ 
+    // Obsolete and CompilerMessage(IsError=true) should not appear.
+    [<Test>]
+    member public this.``ObsoleteAndOCamlCompatDontAppear``() = 
+        let code=
+            [    
+                "open System" 
+                "type X = "
+                "    static member private Private() = ()"
+                "    [<Obsolete>]"
+                "    static member Obsolete() = ()"
+                "    [<CompilerMessage(\"This construct is for ML compatibility.\", 62, IsHidden=true)>]"
+                "    static member CompilerMessageTest() = ()"
+                "X."
+            ]
+        let (_, _, file) = this.CreateSingleFileProject(code)
+        MoveCursorToEndOfMarker(file,"X.")
+        let completions = time1 AutoCompleteAtCursor file "Time of first autocomplete."
+        for completion in completions do
+            match completion with 
+              | ("Obsolete" as s,_,_,_) 
+              //| ("Private" as s,_,_,_)  this isn't supported yet
+              | ("CompilerMessageTest" as s,_,_,_)-> failwith (sprintf "Unexpected item %s at top level."  s)
+              | _ -> ()              
+    
+    // Test various configurations of nested obsolete modules & types
+    // (also test whether we show the right intellisense)    
+    member public this.AutoCompleteObsoleteTest testLine appendDot should shouldnot =        
+        let code = 
+          [ "[<System.ObsoleteAttribute(\"!\", false)>]"
+            "module ObsoleteTop ="
+            "  let T = \"T\""
+            "module Module = "
+            "  [<System.ObsoleteAttribute(\"!\", false)>]"
+            "  module ObsoleteM ="
+            "    let A = \"A\""
+            "    [<System.ObsoleteAttribute(\"!\", false)>]"
+            "    module ObsoleteNested ="
+            "      let C = \"C\""
+            "  [<System.ObsoleteAttribute(\"!\", false)>]"
+            "  type ObsoleteT = "
+            "    static member B = \"B\""
+            "  let Other = 0"
+            "let mutable level = \"\""
+            "" ]
+        let (_, _, file) = this.CreateSingleFileProject(code @ [ testLine ])
+        
+        TakeCoffeeBreak(this.VS)
+        let gpatcc = GlobalParseAndTypeCheckCounter.StartNew(this.VS)
+        if not appendDot then        
+            // In this case, we want to check Ctrl+J completions
+            // For "level <- O" this shows completions starting with O (e.g. Other)
+            MoveCursorToEndOfMarker(file, testLine)
+            let completions = CtrlSpaceCompleteAtCursor file
+            AssertCompListContainsAll(completions, should)
+            AssertCompListDoesNotContainAny(completions, shouldnot) 
+        else
+            // In this case, we quickly type "." and then get dot-completions
+            // For "level <- Module" this shows completions from the "Module" (e.g. "Module.Other")
+            // This simulates the case when the user quickly types "dot" after the file has been TCed before.
+            ReplaceFileInMemoryWithoutCoffeeBreak file (code @ [ testLine + "." ])      
+            MoveCursorToEndOfMarker(file, testLine + ".")
+            let completions = AutoCompleteAtCursor file
+            AssertCompListContainsAll(completions, should)
+            AssertCompListDoesNotContainAny(completions, shouldnot) 
+        gpatcc.AssertExactly(0,0)
+
+    // When the module isn't empty, we should show completion for the module
+    // (and not type-inferrence based completion on strings - therefore test for 'Chars')
+    
+    [<Test>]
+    member public this.``Obsolete.TopLevelModule``() =
+      this.AutoCompleteObsoleteTest "level <- O" false [ "None" ] [ "ObsoleteTop"; "Chars" ]
+
+    [<Test>]
+    member public this.``Obsolete.NestedTypeOrModule``() =
+      this.AutoCompleteObsoleteTest "level <- Module" true [ "Other" ] [ "ObsoleteM"; "ObsoleteT"; "Chars" ]
+
+    [<Test>]
+    member public this.``Obsolete.CompletionOnObsoleteModule.Bug3992``() =
+      this.AutoCompleteObsoleteTest "level <- Module.ObsoleteM" true [ "A" ] [ "ObsoleteNested"; "Chars" ]
+
+    [<Test>]
+    member public this.``Obsolete.DoubleNested``() =
+      this.AutoCompleteObsoleteTest "level <- Module.ObsoleteM.ObsoleteNested" true [ "C" ] [ "Chars" ]
+
+    [<Test>]
+    member public this.``Obsolete.CompletionOnObsoleteType``() =
+      this.AutoCompleteObsoleteTest "level <- Module.ObsoleteT" true [ "B" ] [ "Chars" ]
+
+    /// BUG: Referencing a non-existent DLL caused an assert.
+    [<Test;Category("Repro")>]
+    member public this.``WithNonExistentDll``() = 
+        use _guard = this.UsingNewVS()
+        let solution = this.CreateSolution()
+        let project = CreateProject(solution,"testproject")
+        // in the project system, 'AddAssemblyReference' would throw, so just poke this into the .fsproj file
+        PlaceIntoProjectFileBeforeImport
+            (project, @"
+                <ItemGroup>
+                    <Reference Include=""..\bar\nonexistent.dll"" />
+                </ItemGroup>")
+        let file = AddFileFromText(project,"File1.fs",
+                                    [    
+                                        "(*marker*)  "
+                                     ])
+        let file = OpenFile(project,"File1.fs")
+        
+        MoveCursorToEndOfMarker(file,"(*marker*) ")
+        let completions = CtrlSpaceCompleteAtCursor file
+        AssertCompListContainsAll(completions,[
+                                                "System"; // .NET namespaces
+                                                "Array2D"]) // Types in the F# library
+        AssertCompListDoesNotContain(completions,"Int32") // Types in the System namespace        
+
+    member internal this.AutoCompleteDuplicatesTest (marker, shortName, fullName:string) =
+        let code =
+            [  
+                "namespace A "
+                "module Test = "
+                "  let foo n = n + 1"
+                "  let (|Pat|) x = x + 1"
+                "  exception Failed"
+                "  type Del = delegate of int -> int"
+                "  type A = | Foo"
+                "  type B = | Bar = 0"
+                "type TestType ="
+                "  static member Prop = 0"
+                "  static member Event = (new Event<_>()).Publish"
+                "namespace B"
+                "open A"
+                "open A"
+                marker ]
+        let (_, _, file) = this.CreateSingleFileProject(code)
+        MoveCursorToEndOfMarker(file, marker)
+        let completions = AutoCompleteAtCursor file
+        let (_, _, descrFunc, _) = completions |> Array.find (fun (name, _, _, _) -> name = shortName)
+        let descr = descrFunc()
+        // Check whether the description contains the name only once        
+        let occurrences = ("  " + descr + "  ").Split([| fullName |], System.StringSplitOptions.None).Length - 1
+        AssertEqualWithMessage(1, occurrences, "The entry for '" + fullName + "' is duplicated.")
+
+    // Return the number of occurrences of the specified method in a tooltip string
+    member this.CountMethodOccurrences(descr, methodName:string) =
+        let occurrences = ("  " + descr + "  ").Split([| methodName |], System.StringSplitOptions.None).Length - 1
+        // This is some tag in the tooltip that also contains the overload name text
+        if descr.Contains("[Signature:") then occurrences - 1 else occurrences
+                                      
+    [<Test>]
+    member public this.``Duplicates.Bug4103b``() = 
+        for args in 
+              [ "Test.", "foo", "foo"; 
+                "Test.", "Pat", "Pat";
+                "Test.", "Failed", "exception Failed";
+                "Test.", "Del", "type Del"; 
+                "Test.", "Foo", "Test.A.Foo"
+                "Test.B.", "Bar", "Test.B.Bar"
+                "TestType.", "Prop", "TestType.Prop"
+                "TestType.", "Event", "TestType.Event" ] do   
+            this.AutoCompleteDuplicatesTest args      
+
+    [<Test>]
+    member public this.``Duplicates.Bug4103c``() =       
+        let code =
+            [  
+                "open System.IO"
+                "open System.IO"
+                "File." ]         
+        let (_, _, file) = this.CreateSingleFileProject(code)
+        MoveCursorToEndOfMarker(file, "File.")
+        let completions = AutoCompleteAtCursor file
+        
+        // Get description for Expr.Var
+        let (_, _, descrFunc, _) = completions |> Array.find (fun (name, _, _, _) -> name = "Open")
+        let occurrences = this.CountMethodOccurrences(descrFunc(), "File.Open")
+        AssertEqualWithMessage(3, occurrences, "Found wrong number of overloads for 'File.Open'.")
+
+    [<Test>]
+    member public this.``Duplicates.Bug2094``() =        
+        let code = 
+            [  
+                "open Microsoft.FSharp.Control"
+                "let b = MailboxProcessor." ]
+        let (_, _, file) = this.CreateSingleFileProject(code)
+        MoveCursorToEndOfMarker(file, "MailboxProcessor.")
+        let completions = AutoCompleteAtCursor file
+          
+        // Get description for Expr.Var
+        let (_, _, descrFunc, _) = completions |> Array.find (fun (name, _, _, _) -> name = "Start")
+        let occurrences = this.CountMethodOccurrences(descrFunc(), "Start")        
+        AssertEqualWithMessage(1, occurrences, "Found wrong number of overloads for 'MailboxProcessor.Start'.")
+       
+    [<Test;Category("Repro")>]
+    member public this.``WithinMatchClause.Bug1603``() =        
+        let code = 
+                                    [  
+                                      "let rec f l ="
+                                      "    match l with"
+                                      "    | [] ->"
+                                      "        let xx = System.DateTime.Now"
+                                      "        let y = xx."
+                                      "    | x :: xs -> f xs"
+                                     ]
+        let (_, _, file) = this.CreateSingleFileProject(code)
+        MoveCursorToEndOfMarker(file,"let y = xx.")
+        let completions = AutoCompleteAtCursor file
+        // Should contain something
+        Assert.AreNotEqual(0,completions.Length)      
+        Assert.IsTrue(completions |> Array.exists (fun (name,_,_,_) -> name.Contains("AddMilliseconds")))  
+        
+    // FEATURE: Saving file N does not cause files 1 to N-1 to re-typecheck (but does cause files N to <end> to 
+    [<Test>]
+    [<Category("PerfCheck")>]
+    member public this.``Performance.Bug5774``() =
+        use _guard = this.UsingNewVS()
+        let solution = this.CreateSolution()
+        let project = CreateProject(solution,"testproject")
+        
+        let file1 = AddFileFromText(project,"File1.fs", [""])
+        let file1 = OpenFile(project,"File1.fs")
+        //file1.
+
+        let file2 = AddFileFromText(project,"File2.fs", ["let x = 4"; "x."])
+        let file2 = OpenFile(project,"File2.fs")
+
+        let file3 = AddFileFromText(project,"File3.fs", [""])
+        let file3 = OpenFile(project,"File3.fs")
+
+        // ensure that the incremental builder is running        
+        MoveCursorToEndOfMarker(file2,"x.")
+        AutoCompleteAtCursor file2 |> ignore
+
+        // Start the key instrumentation
+        let gpatcc = GlobalParseAndTypeCheckCounter.StartNew(this.VS)
+        
+        // Save file2
+        ReplaceFileInMemory file2 [""]
+        SaveFileToDisk file2      
+        TakeCoffeeBreak(this.VS)
+        
+        gpatcc.AssertExactly(notAA[file2], notAA[file2;file3])
+
+    /// FEATURE: References added to the project bring corresponding new .NET and F# items into scope.
+    [<Test;Category("ReproX")>]
+    member public this.``AfterAssemblyReferenceAdded``() =
+        use _guard = this.UsingNewVS()
+        let solution = this.CreateSolution()
+        let project = CreateProject(solution,"testproject")
+        let file = AddFileFromText(project,"File1.fs",
+                                    [ 
+                                     "let y = System.Deployment.Application."
+                                     "()"])
+        let file = OpenFile(project, "File1.fs")
+        MoveCursorToEndOfMarker(file,"System.Deployment.Application.")
+        let completions = AutoCompleteAtCursor(file)
+        // printf "Completions=%A\n" completions
+        Assert.AreEqual(0, completions.Length) // Expect none here because reference hasn't been added.
+        
+        // Now, add a reference to the given assembly.
+        this.AddAssemblyReference(project,"System.Deployment")
+
+        TakeCoffeeBreak(this.VS)
+        let completions = AutoCompleteAtCursor(file)
+        Assert.AreNotEqual(0, completions.Length, "Expected some items in the list after adding a reference.") 
+
+    /// FEATURE: Updating the active project configuration influences the language service
+    [<Test>]
+    member public this.``AfterUpdateProjectConfiguration``() = 
+        use _guard = this.UsingNewVS()
+        let solution = this.CreateSolution()
+        let project = CreateProject(solution,"testproject")
+        PlaceIntoProjectFileBeforeImport
+            (project, @"
+                <ItemGroup>
+                    <Reference Include=""System.Deployment"" Condition=""'$(Configuration)'=='Foo'"" />
+                </ItemGroup>")
+        let file = AddFileFromText(project,"File1.fs",
+                                    [ 
+                                     "let y = System.Deployment.Application."
+                                     "()"])
+        let file = OpenFile(project, "File1.fs")
+        MoveCursorToEndOfMarker(file,"System.Deployment.Application.")
+        let completions = AutoCompleteAtCursor(file)
+        // printf "Completions=%A\n" completions
+        Assert.AreEqual(0, completions.Length) // Expect none here because reference hasn't been added.
+        
+        // Now, update active configuration
+        SetConfigurationAndPlatform(project, "Foo|x86")
+        TakeCoffeeBreak(this.VS)
+        let completions = AutoCompleteAtCursor(file)
+        Assert.AreNotEqual(0, completions.Length, "Expected some items in the list after updating configuration.") 
+
+    /// FEATURE: Updating the active project platform influences the language service
+    [<Test>]
+    member public this.``AfterUpdateProjectPlatform``() = 
+        use _guard = this.UsingNewVS()
+        let solution = this.CreateSolution()
+        let project = CreateProject(solution,"testproject")
+        PlaceIntoProjectFileBeforeImport
+            (project, @"
+            <ItemGroup>
+                <Reference Include=""System.Deployment"" Condition=""'$(Platform)'=='x86'"" />
+            </ItemGroup>")
+        SetConfigurationAndPlatform(project, "Debug|AnyCPU")
+        let file = AddFileFromText(project,"File1.fs",
+                                    [ 
+                                     "let y = System.Deployment.Application."
+                                     "()"])
+        let file = OpenFile(project, "File1.fs")
+        MoveCursorToEndOfMarker(file,"System.Deployment.Application.")
+        let completions = AutoCompleteAtCursor(file)
+        // printf "Completions=%A\n" completions
+        Assert.AreEqual(0, completions.Length) // Expect none here because reference hasn't been added.
+        
+        // Now, update active platform
+        SetConfigurationAndPlatform(project, "Debug|x86")
+        let completions = AutoCompleteAtCursor(file)
+        Assert.AreNotEqual(0, completions.Length, "Expected some items in the list after updating platform.") 
+
+    /// FEATURE: The filename on disk and the filename in the project can differ in case.
+    [<Test>]
+    [<Category("PerfCheck")>]
+    member this.``Filenames.MayBeDifferentlyCased``() =
+        use _guard = this.UsingNewVS() 
+        let solution = this.CreateSolution()
+        let project = CreateProject(solution,"testproject")
+        let file = AddFileFromTextEx(project,"file1.fs","FILE1.FS",BuildAction.Compile,
+                                    [ 
+                                     "let y = System.Deployment.Application."
+                                     "()"])
+        let file = OpenFile(project, "file1.fs")
+        MoveCursorToEndOfMarker(file,"System.Deployment.Application.")
+        let completions = AutoCompleteAtCursor(file)
+        // printf "Completions=%A\n" completions
+        Assert.AreEqual(0, completions.Length) // Expect none here because reference hasn't been added.
+        
+        // Now, add a reference to the given assembly.
+        this.AddAssemblyReference(project,"System.Deployment")
+        let completions = AutoCompleteAtCursor(file)
+        Assert.AreNotEqual(0, completions.Length, "Expected some items in the list after adding a reference.") 
+        
+    /// In this bug, a bogus flag caused the rest of flag parsing to be ignored.
+    [<Test>]
+    [<Category("PerfCheck")>]
+    member public this.``FlagsAndSettings.Bug1969``() = 
+        use _guard = this.UsingNewVS()
+        let solution = this.CreateSolution()
+        let project = CreateProject(solution,"testproject")
+        
+        
+        let file = AddFileFromText(project,"File1.fs",
+                                    [ 
+                                     "let y = System.Deployment.Application."
+                                     "()"])
+        let file = OpenFile(project, "File1.fs")
+        MoveCursorToEndOfMarker(file,"System.Deployment.Application.")
+        let completions = AutoCompleteAtCursor(file)
+        // printf "Completions=%A\n" completions
+        Assert.AreEqual(0, completions.Length) // Expect none here because reference hasn't been added.
+        
+        // Add an unknown flag followed by the reference to our assembly.
+        let deploymentAssembly = sprintf @"%s\Microsoft.NET\Framework\v2.0.50727\System.Deployment.dll" (System.Environment.GetEnvironmentVariable("windir"))
+        SetOtherFlags(project,"--doo-da -r:" + deploymentAssembly) 
+        let completions = AutoCompleteAtCursor(file)
+        // Now, make sure the reference added after the erroneous reference is still honored.       
+        Assert.AreNotEqual(0, completions.Length, "Expected some items in the list after adding a reference.")         
+        ShowErrors(project)      
+        
+    /// In this bug there was an exception if the user pressed dot after a long identifier
+    /// that was unknown.
+    [<Test>]
+    member public this.``OfSystemWindows``() = 
+        let code = ["let y=new System.Windows."]
+        let (_, _, file) = this.CreateSingleFileProject(code, references = ["System.Windows.Forms"])
+        MoveCursorToEndOfMarker(file,"System.Windows.")
+        let completions = AutoCompleteAtCursor(file)
+        printfn "Completions=%A" completions
+        Assert.AreEqual(1, completions.Length)
+        
+    /// Tests whether we're correctly showing both type and module when they have the same name
+    [<Test>]
+    member public this.``ShowSetAsModuleAndType``() = 
+        let code = ["let s = Set"]
+        let (_, _, file) = this.CreateSingleFileProject(code)
+        MoveCursorToEndOfMarker(file,"= Set")
+        let completions = CtrlSpaceCompleteAtCursor(file)
+        let found = completions |> Array.tryFind (fun (n, _, _, _) -> n = "Set")
+        match found with 
+        | Some(_, _, f, _) ->
+            let tip = f()
+            AssertContains(tip, "module Set")        
+            AssertContains(tip, "type Set")        
+        | _ -> 
+            Assert.Fail("'Set' not found in the completion list")           
+        
+    /// FEATURE: The user may type namespace followed by dot and see a completion list containing members of that namespace.
+    [<Test>]
+    member public this.``AtNamespaceDot``() = 
+        let code = ["let y=new System.String()"]
+        let (_, _, file) = this.CreateSingleFileProject(code)
+        MoveCursorToEndOfMarker(file,"System.")
+        let completions = AutoCompleteAtCursor(file)
+        Assert.IsTrue(completions.Length>0)
+        
+    /// FEATURE: The user will see appropriate glyphs in the autocompletion list.
+    [<Test>]
+    member public this.``OfSeveralModuleMembers``() = 
+        let code = 
+                                    [ 
+                                     "module Module ="
+                                     "    let Constant = 5"
+                                     "    type Class = class"
+                                     "       end"
+                                     "    type Record = {AString:string}"
+                                     "    exception OutOfRange of string"
+                                     "    type Enum = Red = 0 | White = 1 | Blue = 2"
+                                     "    type DiscriminatedUnion = A | B | C"
+                                     "    type AsmType = (# \"!0[]\" #)"
+                                     "    type TupleType = int * int"
+                                     "    type FunctionType = unit->unit"
+                                     "    let (~+) x = -x"
+                                     "    type Interface ="
+                                     "        abstract MyMethod : unit->unit"
+                                     "    type Struct = struct"
+                                     "        end"
+                                     "    let Function x = 0"
+                                     "    let FunctionValue = fun x -> 0"
+                                     "    let Tuple = (0,2)"
+                                     "    module Submodule ="
+                                     "        let a = 0"
+                                     "    type ValueType = int"
+                                     "module AbbreviationModule ="
+                                     "    type StructAbbreviation = Module.Struct"
+                                     "    type InterfaceAbbreviation = Module.Interface"
+                                     "    type DiscriminatedUnionAbbreviation = Module.DiscriminatedUnion"
+                                     "    type RecordAbbreviation = Module.Record"
+                                     "    type EnumAbbreviation = Module.Enum"
+                                     "    type TupleTypeAbbreviation = Module.TupleType"
+                                     "    type AsmTypeAbbreviation = Module.AsmType"
+                                     "let y = AbbreviationModule."
+                                     "let y = Module."
+                                     "let f x = 0"
+                                    ]
+        let (_, _, file) = this.CreateSingleFileProject(code)
+        MoveCursorToEndOfMarker(file," Module.")
+        let completions = time1 AutoCompleteAtCursor file "Time of first autocomplete."
+
+        Assert.IsTrue(completions.Length>0)
+        for completion in completions do
+            match completion with 
+              | "A",_,_,DeclarationType.EnumMember -> ()
+              | "B",_,_,DeclarationType.EnumMember -> ()
+              | "C",_,_,DeclarationType.EnumMember -> ()
+              | "Function",_,_,DeclarationType.Constant -> ()
+              | "Enum",_,_,DeclarationType.Enum -> ()
+              | "Constant",_,_,DeclarationType.Constant -> ()
+              | "Function",_,_,DeclarationType.FunctionValue -> ()
+              | "FunctionValue",_,_,DeclarationType.FunctionValue -> ()
+              | "OutOfRange",_,_,DeclarationType.Exception -> ()
+              | "OutOfRangeException",_,_,DeclarationType.Class -> ()
+              | "Interface",_,_,DeclarationType.Interface -> ()
+              | "Struct",_,_,DeclarationType.ValueType -> ()
+              | "Tuple",_,_,DeclarationType.Constant -> ()
+              | "Submodule",_,_,DeclarationType.Module -> ()
+              | "Record",_,_,DeclarationType.Record -> ()
+              | "DiscriminatedUnion",_,_,DeclarationType.DiscriminatedUnion -> ()
+              | "AsmType",_,_,DeclarationType.RareType -> ()
+              | "FunctionType",_,_,DeclarationType.FunctionType -> ()
+              | "TupleType",_,_,DeclarationType.ValueType -> ()
+              | "ValueType",_,_,DeclarationType.ValueType -> ()
+              | "Class",_,_,DeclarationType.Class -> ()
+              | "Int32",_,_,DeclarationType.Method -> ()
+              | "TupleTypeAbbreviation",_,_,DeclarationType.Constant -> ()
+              | name,_,_,x -> failwith (sprintf "Unexpected module member %s seen with declaration type %A" name x)
+
+        MoveCursorToEndOfMarker(file,"AbbreviationModule.")
+        let completions = time1 AutoCompleteAtCursor file "Time of second autocomplete."
+        // printf "Completions=%A\n" completions
+        Assert.IsTrue(completions.Length>0)
+        for completion in completions do
+            match completion with 
+              | "Int32",_,_,_ | "Function",_,_,_
+              | "Enum",_,_,_ | "Constant",_,_,_
+              | "Function",_,_,_ | "Interface",_,_,_ 
+              | "Struct",_,_,_ | "Tuple",_,_,_ 
+              | "Record",_,_,_ -> ()
+              | "EnumAbbreviation",_,_,DeclarationType.Enum -> ()
+              | "InterfaceAbbreviation",_,_,DeclarationType.Interface -> ()
+              | "StructAbbreviation",_,_,DeclarationType.ValueType -> ()
+              | "DiscriminatedUnion",_,_,_ -> ()
+              | "RecordAbbreviation",_,_,DeclarationType.Record -> ()
+              | "DiscriminatedUnionAbbreviation",_,_,DeclarationType.DiscriminatedUnion -> ()
+              | "AsmTypeAbbreviation",_,_,DeclarationType.RareType -> ()
+              | "TupleTypeAbbreviation",_,_,DeclarationType.ValueType -> ()
+              | name,_,_,x -> failwith (sprintf "Unexpected union member %s seen with declaration type %A" name x)
+        
+    [<Test>]
+    member public this.``ListFunctions``() = 
+        let code = 
+                                    [ 
+                                     "let y = List."
+                                     "let f x = 0"
+                                    ]
+        let (_,_, file) = this.CreateSingleFileProject(code)
+        MoveCursorToEndOfMarker(file,"List.")
+        let completions = time1 AutoCompleteAtCursor file "Time of first autocomplete."
+        // printf "Completions=%A\n" completions
+        Assert.IsTrue(completions.Length>0)
+        for completion in completions do
+            match completion with 
+              | "Cons",_,_,DeclarationType.Method -> ()
+              | "Equals",_,_,DeclarationType.Method -> ()
+              | "Empty",_,_,DeclarationType.Property -> () 
+              | "empty",_,_,DeclarationType.Constant -> () 
+              | _,_,_,DeclarationType.FunctionValue -> ()
+              | name,_,_,x -> failwith (sprintf "Unexpected item %s seen with declaration type %A" name x)
+
+    [<Test>]
+    member public this.``SystemNamespace``() =
+        let code =
+                                    [ 
+                                     "let y = System."
+                                    ]         
+        let (_,_, file) = this.CreateSingleFileProject(code)
+        MoveCursorToEndOfMarker(file,"System.")
+        let completions = time1 AutoCompleteAtCursor file "Time of first autocomplete."
+        // printf "Completions=%A\n" completions
+        Assert.IsTrue(completions.Length>0)
+        
+        let AssertIsDecl(name,decl,expected) =
+            if decl<>expected then failwith (sprintf "Expected %A for %s but was %A" expected name decl)
+        
+        for completion in completions do
+            match completion with 
+              | "Action" as name,_,_,decl -> AssertIsDecl(name,decl,DeclarationType.FunctionType)
+              | "CodeDom" as name,_,_,decl -> AssertIsDecl(name,decl,DeclarationType.Namespace)
+              | _ -> ()
+      
+    // If there is a compile error that prevents a data tip from resolving then show that data tip.
+    [<Test>]
+    member public this.``MemberInfoCompileErrorsShowInDataTip``() =     
+        let code = 
+                                    [ 
+                                     "type Foo = "
+                                     "    member x.Bar() = 0" 
+                                     "let foovalue:Foo = unbox null"
+                                     "foovalue.B" // make sure this is different from the line 3!
+                                    ]
+        let (_,_, file) = this.CreateSingleFileProject(code)
+        MoveCursorToEndOfMarker(file,"foovalue.B") 
+    
+        use scope = AutoCompleteMemberDataTipsThrowsScope(this.VS, "Simulated compiler error")
+        let completions = time1 CtrlSpaceCompleteAtCursor file "Time of first autocomplete."
+        Assert.IsTrue(completions.Length>0)      
+        for completion in completions do 
+            let _,_,descfunc,_ = completion
+            let desc = descfunc()
+            AssertContains(desc,"Simulated compiler error")
+
+    // Bunch of crud in empty list. This test asserts that unwanted things don't exist at the top level.
+    [<Test>]
+    member public this.``Editor.WhitoutContext.Bug986``() =     
+        let code = ["(*mark*)"]
+        let (_,_, file) = this.CreateSingleFileProject(code)
+
+        MoveCursorToEndOfMarker(file,"(*mark*)")
+        let completions = time1 CtrlSpaceCompleteAtCursor file "Time of first autocomplete."
+        for completion in completions do
+            match completion with 
+              | ("IChapteredRowset" as s,_,_,_) 
+              | ("ICorRuntimeHost" as s,_,_,_)-> failwith (sprintf "Unexpected item %s at top level."  s)
+              | _ -> ()
+              
+    [<Test>]
+    member public this.``LetBind.TopLevel.Bug1650``() =   
+        let code =["let x = "]          
+        let (_,_, file) = this.CreateSingleFileProject(code)
+        let gpatcc = GlobalParseAndTypeCheckCounter.StartNew(this.VS)
+        MoveCursorToEndOfMarker(file,"let x = ")
+        let completions = time1 CtrlSpaceCompleteAtCursor file "Time of first autocomplete."
+        Assert.IsTrue(completions.Length>0)
+        gpatcc.AssertExactly(0,0)
+              
+    [<Test>]
+    member public this.``Identifier.Invalid.Bug876b``() =  
+        let code =
+                                    [ 
+                                     "let f (x:System.Windows.Forms.Form) = x."
+                                     "  for x = 0 to 0 do () done"
+                                    ]
+        let (_,project, file) = this.CreateSingleFileProject(code, references = ["System"; "System.Drawing"; "System.Windows.Forms"])
+
+        MoveCursorToEndOfMarker(file,"x.")
+        let completions = time1 AutoCompleteAtCursor file "Time of first autocomplete."
+        ShowErrors(project)
+        Assert.IsTrue(completions.Length>0)      
+        
+    [<Test>]
+    member public this.``Identifier.Invalid.Bug876c``() =     
+        let code =
+                                    [ 
+                                     "let f (x:System.Windows.Forms.Form) = x."
+                                     "  12"
+                                    ]
+        let (_,_, file) = this.CreateSingleFileProject(code, references = ["System"; "System.Drawing"; "System.Windows.Forms"])
+        MoveCursorToEndOfMarker(file,"x.")
+        let completions = time1 AutoCompleteAtCursor file "Time of first autocomplete."
+        Assert.IsTrue(completions.Length>0)     
+        
+    [<Test>]
+    member public this.``EnumValue.Bug2449``() =     
+        let code =
+                                    [ 
+                                     "type E = | A = 1 | B = 2"
+                                     "let e = E.A"
+                                     "e."
+                                    ]
+        let (_, _, file) = this.CreateSingleFileProject(code)
+        MoveCursorToEndOfMarker(file,"e.")
+        let completions = time1 AutoCompleteAtCursor file "Time of first autocomplete."
+        AssertCompListDoesNotContain(completions, "value__")
+               
+    [<Test>]
+    member public this.``EnumValue.Bug4044``() =   
+        let code =
+                                    [ 
+                                     "open System.IO"
+                                     "let GetFileSize filePath = File.GetAttributes(filePath)."
+                                    ]
+        let (_, _, file) = this.CreateSingleFileProject(code)
+        let gpatcc = GlobalParseAndTypeCheckCounter.StartNew(this.VS)
+        MoveCursorToEndOfMarker(file,"filePath).")
+        let completions = time1 AutoCompleteAtCursor file "Time of first autocomplete."
+        AssertCompListDoesNotContain(completions, "value__")
+        gpatcc.AssertExactly(0,0)
+                            
+    /// There was a bug (2584) that IntelliSense should treat 'int' as a type instead of treating it as a function
+    /// However, this is now deprecated behavior. We want the user to use 'System.Int32' and 
+    /// we generally prefer information from name resolution (aslo see 4405)
+    [<Test>]
+    member public this.``PrimTypeAndFunc``() =     
+        let code =
+                                    [ 
+                                     "System.Int32. "
+                                     "int. "
+                                    ]
+        let (_, _, file) = this.CreateSingleFileProject(code)
+        MoveCursorToEndOfMarker(file,"System.Int32.")
+        let completions = time1 AutoCompleteAtCursor file "Time of first autocomplete."
+        AssertCompListContains(completions,"MinValue")
+
+        MoveCursorToEndOfMarker(file,"int.")
+        let completions = time1 AutoCompleteAtCursor file "Time of first autocomplete."
+        AssertCompListDoesNotContain(completions,"MinValue")
+           
+ /// This is related to Bug1605--since the file couldn't parse there was no information to provide the autocompletion list.    
+    [<Test>]
+    member public this.``MatchStatement.Clause.AfterLetBinds.Bug1603``() = 
+        let code =
+                                    [ 
+                                     "let rec f l ="
+                                     "    match l with"
+                                     "    | [] ->"
+                                     "        let xx = System.DateTime.Now"
+                                     "        let y = xx"
+                                     "    | x :: xs -> f xs."
+                                    ]
+        let (_, _, file) = this.CreateSingleFileProject(code)
+        MoveCursorToEndOfMarker(file,"xs -> f xs.")
+        let completions = time1 AutoCompleteAtCursor file "Time of first autocomplete."
+        // printf "Completions=%A\n" completions
+        Assert.IsTrue(completions.Length>0)
+        
+        let mutable count = 0
+        
+        let AssertIsDecl(name,decl,expected) =
+            if decl<>expected then failwith (sprintf "Expected %A for %s but was %A" expected name decl)
+                    
+        for completion in completions do
+            match completion with 
+              | "Head" as name,_,_,decl -> 
+                count<-count + 1
+                AssertIsDecl(name,decl,DeclarationType.Property) 
+              | "Tail" as name,_,_,decl -> 
+                count<-count + 1
+                AssertIsDecl(name,decl,DeclarationType.Property) 
+              | name,_,_,x -> ()        
+        
+        Assert.AreEqual(2,count)
+        
+    // This was a bug in which the third level of dotting was ignored.
+    [<Test>]
+    member public this.``ThirdLevelOfDotting``() =     
+        let code =
+                                    [ 
+                                     "let x = System.Console.Wr"
+                                    ]
+        let (_, _, file) = this.CreateSingleFileProject(code)
+        MoveCursorToEndOfMarker(file,"Console.Wr")
+        let completions = time1 CtrlSpaceCompleteAtCursor file "Time of first autocomplete."
+        // printf "Completions=%A\n" completions
+        Assert.IsTrue(completions.Length>0)
+        
+        let AssertIsDecl(name,decl,expected) =
+            if decl<>expected then failwith (sprintf "Expected %A for %s but was %A" expected name decl)
+                    
+        for completion in completions do
+            match completion with 
+              | "BackgroundColor" as name,_,_,decl -> AssertIsDecl(name,decl,DeclarationType.Property) 
+              | "CancelKeyEvent" as name,_,_,decl -> AssertIsDecl(name,decl,DeclarationType.Event) 
+              | name,_,_,x -> ()
+
+    // Test completions in an incomplete computation expression (case 1: for "let")
+    [<Test>]
+    member public this.``ComputationExpressionLet``() =     
+        let code =
+                    [  
+                      "let http(url:string) = "
+                      "  async { "
+                      "    let rnd = new System.Random()"
+                      "    let rsp = rnd.N" ]
+        let (_, _, file) = this.CreateSingleFileProject(code)
+        MoveCursorToEndOfMarker(file,"rsp = rnd.")
+        let completions = time1 AutoCompleteAtCursor file "Time of first autocomplete."
+        AssertCompListContainsAll(completions, ["Next"])
+ 
+    [<Test>]
+    member public this.``BestMatch.Bug4320a``() = 
+        let code = [ " let x = System." ]
+        let (_, _, file) = this.CreateSingleFileProject(code)
+        MoveCursorToEndOfMarker(file,"System.")
+        let Match text filterText = CompletionBestMatchAtCursorFor(file, text, filterText)
+        // (ItemName, isUnique, isPrefix)
+        // isUnique=true means it will be selected on ctrl-space invocation
+        // isPrefix=true means it will be selected, instead of just outlined
+        AssertEqual(Some ("GC", false, true),                Match "G" None)
+        AssertEqual(Some ("GC", false, true),                Match "GC" None)
+        AssertEqual(Some ("GCCollectionMode", true, true),   Match "GCC" None)
+        AssertEqual(Some ("GCCollectionMode", false, false), Match "GCCZ" None)
+        AssertEqual(Some ("GC", false, true),                Match "G" (Some "G"))
+        AssertEqual(Some ("GC", false, true),                Match "GC" (Some "G"))
+        AssertEqual(Some ("GCCollectionMode", true, true),   Match "GCC" (Some "G"))
+        AssertEqual(Some ("GCCollectionMode", false, false), Match "GCCZ" (Some "G"))
+        AssertEqual(Some ("GC", false, true),                Match "G" (Some "GC"))
+        AssertEqual(Some ("GC", false, true),                Match "GC" (Some "GC"))
+        AssertEqual(Some ("GCCollectionMode", true, true),   Match "GCC" (Some "GC"))
+        AssertEqual(Some ("GCCollectionMode", false, false), Match "GCCZ" (Some "GC"))
+    
+    [<Test>]
+    member public this.``BestMatch.Bug4320b``() = 
+        let code = [ " let x = List." ]
+        let (_, _, file) = this.CreateSingleFileProject(code)
+        MoveCursorToEndOfMarker(file,"List.")
+        let Match text = CompletionBestMatchAtCursorFor(file, text, None)
+        // (ItemName, isUnique, isPrefix)
+        // isUnique=true means it will be selected on ctrl-space invocation
+        // isPrefix=true means it will be selected, instead of just outlined
+        AssertEqual(Some ("choose", false, true),  Match "c")
+        AssertEqual(Some ("collect", false, true), Match "co")
+        AssertEqual(Some ("concat", true, true),   Match "con")
+        AssertEqual(Some ("Cons", true, true),     Match "cons")
+      
+    [<Test>]
+    member public this.``BestMatch.Bug5131``() = 
+        let code = [ "System.Environment." ]
+        let (_, _, file) = this.CreateSingleFileProject(code)
+        MoveCursorToEndOfMarker(file,"Environment.")
+        let Match text = CompletionBestMatchAtCursorFor(file, text, None)
+        // (ItemName, isUnique, isPrefix)
+        // isUnique=true means it will be selected on ctrl-space invocation
+        // isPrefix=true means it will be selected, instead of just outlined
+        AssertEqual(Some ("OSVersion", true, true),  Match "o")
+    
+    [<Test>]
+    member public this.``COMPILED.DefineNotPropagatedToIncrementalBuilder``() =
+        use _guard = this.UsingNewVS()
+ 
+        let solution = this.CreateSolution()
+        let projName = "testproject"
+        let project = CreateProject(solution,projName)
+        let dir = ProjectDirectory(project)
+        let file1 = AddFileFromText(project,"File1.fs", 
+                                    [ 
+                                     "module File1"
+                                     "#if COMPILED"
+                                     "let x = 0"
+                                     "#else"
+                                     "let y = 1"
+                                     "#endif"
+                                    ]) 
+        let file2 = AddFileFromText(project,"File2.fs", 
+                                    [ 
+                                     "module File2"
+                                     "File1."
+                                    ]) 
+
+        let file = OpenFile(project, "File2.fs")
+        MoveCursorToEndOfMarker(file, "File1.")
+        let completionItems = 
+            AutoCompleteAtCursor(file)
+            |> Array.map (fun (name, _, _, _) -> name)
+        Assert.AreEqual(1, completionItems.Length, "Expected 1 item in the list")
+        Assert.AreEqual("x", completionItems.[0], "Expected 'x' in the list")
+ 
+    [<Test>]
+    member public this.``VisualStudio.CloseAndReopenSolution``() = 
+        use _guard = this.UsingNewVS()
+        // This test exposes what was once a bug, where closing a solution and then re-opening
+        // it caused the old stale IProjectSiteOption (that the LanguageService had cached)
+        // to eventually throw a NullReferenceException and assert.
+        let solution = this.CreateSolution()
+        let projName = "testproject"
+        let project = CreateProject(solution,projName)
+        let dir = ProjectDirectory(project)
+        let file = AddFileFromText(project,"File1.fs", 
+                                    [ 
+                                     "let x = 0"
+                                     "let y = x."
+                                    ]) 
+        let file = OpenFile(project, "File1.fs")
+        MoveCursorToEndOfMarker(file,"x.")
+        let completions = time1 AutoCompleteAtCursor file "Time of first autocomplete."
+        // printf "Completions=%A\n" completions
+        Assert.IsTrue(completions.Length>0)
+        this.CloseSolution(solution)
+        let project,solution = OpenExistingProject(this.VS, dir, projName)
+        let file = List.nth (GetOpenFiles(project)) 0
+        MoveCursorToEndOfMarker(file,"x.")
+        let completions = time1 AutoCompleteAtCursor file "Time of first autocomplete."
+        // printf "Completions=%A\n" completions
+        Assert.IsTrue(completions.Length>0)
+
+    [<Test>]
+    member this.``BadCompletionAfterQuicklyTyping.Bug72561``() =        
+        let code = [ "        " ]
+        let (_, _, file) = this.CreateSingleFileProject(code)
+        
+        TakeCoffeeBreak(this.VS)
+        let gpatcc = GlobalParseAndTypeCheckCounter.StartNew(this.VS)
+        // In this case, we quickly type "." and then get dot-completions
+        // This simulates the case when the user quickly types "dot" after the file has been TCed before.
+        ReplaceFileInMemoryWithoutCoffeeBreak file ([ "[1]." ])      
+        MoveCursorToEndOfMarker(file, ".")
+        // Note: no TakeCoffeeBreak(this.VS)
+        let completions = AutoCompleteAtCursor file
+        AssertCompListContainsExactly(completions, [])  // there are no stale results for an expression at this location, so nothing is returned immediately
+        // second-chance intellisense will kick in:
+        TakeCoffeeBreak(this.VS)
+        let completions = AutoCompleteAtCursor file
+        AssertCompListContainsAll(completions, ["Length"])
+        AssertCompListDoesNotContainAny(completions, ["AbstractClassAttribute"]) 
+        gpatcc.AssertExactly(0,0)
+
+    [<Test>]
+    member this.``BadCompletionAfterQuicklyTyping.Bug72561.Noteworthy.NowWorks``() =        
+        let code = [ "123      " ]
+        let (_, _, file) = this.CreateSingleFileProject(code)
+        
+        TakeCoffeeBreak(this.VS)
+        let gpatcc = GlobalParseAndTypeCheckCounter.StartNew(this.VS)
+        // In this case, we quickly type "." and then get dot-completions
+        // This simulates the case when the user quickly types "dot" after the file has been TCed before.
+        ReplaceFileInMemoryWithoutCoffeeBreak file ([ "[1]." ])      
+        MoveCursorToEndOfMarker(file, ".")
+        // Note: no TakeCoffeeBreak(this.VS)
+        let completions = AutoCompleteAtCursor file
+        AssertCompListIsEmpty(completions)  // empty completion list means second-chance intellisense will kick in
+        // if we wait...
+        TakeCoffeeBreak(this.VS)
+        let completions = AutoCompleteAtCursor file
+        // ... we get the expected answer
+        AssertCompListContainsAll(completions, ["Length"])
+        AssertCompListDoesNotContainAny(completions, ["AbstractClassAttribute"]) 
+        gpatcc.AssertExactly(0,0)
+
+    [<Test>]
+    member this.``BadCompletionAfterQuicklyTyping.Bug130733.NowWorks``() =        
+        let code = [ "let someCall(x) = null"
+                     "let xe = someCall(System.IO.StringReader()  "]
+        let (_, _, file) = this.CreateSingleFileProject(code)
+        
+        TakeCoffeeBreak(this.VS)
+        let gpatcc = GlobalParseAndTypeCheckCounter.StartNew(this.VS)
+        // In this case, we quickly type "." and then get dot-completions
+        // This simulates the case when the user quickly types "dot" after the file has been TCed before.
+        ReplaceFileInMemoryWithoutCoffeeBreak file [ "let someCall(x) = null"
+                                                     "let xe = someCall(System.IO.StringReader(). "]
+        MoveCursorToEndOfMarker(file, "().")
+        // Note: no TakeCoffeeBreak(this.VS)
+        let completions = AutoCompleteAtCursor file
+        AssertCompListContainsAll(completions, ["ReadBlock"]) // text to the left of the dot did not change, so we use stale (correct) result immediately
+        // if we wait...
+        TakeCoffeeBreak(this.VS)
+        let completions = AutoCompleteAtCursor file
+        // ... we get the expected answer
+        AssertCompListContainsAll(completions, ["ReadBlock"])
+        gpatcc.AssertExactly(0,0)
+
+
+    [<Test>]
+    member this.``BadCompletionAfterQuicklyTyping.Bug177519.NowWorking``() =        
+        // this test is similar to "Bug72561.Noteworthy" but uses name resolutions rather than expression typings
+        // name resolutions currently still respond with stale info
+        let code = [ "let A = 42"
+                     "let B = \"\""
+                     "A.    // quickly backspace and retype B. --> exact name resolution code path" ]
+        let (_, _, file) = this.CreateSingleFileProject(code)
+        
+        TakeCoffeeBreak(this.VS)
+        let gpatcc = GlobalParseAndTypeCheckCounter.StartNew(this.VS)
+        let code2= [ "let A = 42"
+                     "let B = \"\""
+                     "B.    // quickly backspace and retype B. --> exact name resolution code path" ]
+        ReplaceFileInMemoryWithoutCoffeeBreak file code2
+        MoveCursorToEndOfMarker(file, "B.")
+        // Note: no TakeCoffeeBreak(this.VS)
+        let completions = AutoCompleteAtCursor file
+        AssertCompListIsEmpty(completions)  // empty completion list means second-chance intellisense will kick in
+        // if we wait...
+        TakeCoffeeBreak(this.VS)
+        let completions = AutoCompleteAtCursor file
+        // ... we get the expected answer
+        AssertCompListContainsAll(completions, ["Chars"])  // has correct string info
+        gpatcc.AssertExactly(0,0)
+                                             
+//*********************************************Previous Completion test and helper*****
+    member private this.VerifyCompListDoesNotContainAnyAtStartOfMarker(fileContents : string, marker : string, list : string list) =
+        let (solution, project, file) = this.CreateSingleFileProject(fileContents)
+        MoveCursorToStartOfMarker(file, marker)    
+        let completions = AutoCompleteAtCursor(file)
+        AssertCompListDoesNotContainAny(completions,list)
+
+    member private this.VerifyCtrlSpaceListDoesNotContainAnyAtStartOfMarker(fileContents : string, marker : string, list : string list) =
+        let (solution, project, file) = this.CreateSingleFileProject(fileContents)
+        MoveCursorToStartOfMarker(file, marker)    
+        let completions = CtrlSpaceCompleteAtCursor file
+        AssertCompListDoesNotContainAny(completions,list)
+
+    member private this.VerifyCompListContainAllAtStartOfMarker(fileContents : string, marker : string, list : string list) =
+        let (solution, project, file) = this.CreateSingleFileProject(fileContents)
+        MoveCursorToStartOfMarker(file, marker)
+        let completions = AutoCompleteAtCursor(file)
+        AssertCompListContainsAll(completions, list)
+
+    member private this.VerifyCtrlSpaceListContainAllAtStartOfMarker(fileContents : string, marker : string, list : string list, ?coffeeBreak:bool, ?addtlRefAssy:list<string>) =
+        let coffeeBreak = defaultArg coffeeBreak false
+        let (solution, project, file) = this.CreateSingleFileProject(fileContents, ?references = addtlRefAssy)
+        MoveCursorToStartOfMarker(file, marker)
+        if coffeeBreak then TakeCoffeeBreak(this.VS)
+        let completions = CtrlSpaceCompleteAtCursor file
+        AssertCompListContainsAll(completions, list)
+
+        
+    member private this.VerifyAutoCompListIsEmptyAtEndOfMarker(fileContents : string, marker : string) =
+        let (solution, project, file) = this.CreateSingleFileProject(fileContents)
+        MoveCursorToEndOfMarker(file, marker)
+        let completions = AutoCompleteAtCursor(file)   
+        AssertEqual(0,completions.Length)              
+
+    member private this.VerifyCtrlSpaceCompListIsEmptyAtEndOfMarker(fileContents : string, marker : string) =
+        let (solution, project, file) = this.CreateSingleFileProject(fileContents)
+        MoveCursorToEndOfMarker(file, marker)
+        let completions = CtrlSpaceCompleteAtCursor(file)   
+        AssertEqual(0,completions.Length)              
+                
+    [<Test>]
+    member this.``Expression.WithoutPreDefinedMethods``() = 
+        this.VerifyCtrlSpaceListDoesNotContainAnyAtStartOfMarker(
+            fileContents = """
+                let x = F(*HERE*)""",
+            marker = "(*HERE*)",
+            list = ["FSharpDelegateEvent"; "PrivateMethod"; "PrivateType"])
+                    
+    [<Test>]
+    member this.``Expression.WithPreDefinedMethods``() = 
+        this.VerifyCtrlSpaceListContainAllAtStartOfMarker(
+            fileContents = """
+                module Module1 =
+                    let private PrivateField = 1    
+                    let private PrivateMethod x = 
+                        x+1        
+                    type private PrivateType() =
+                        member this.mem = 1    
+                    let a = (*Marker1*)
+    
+                    let b = 23
+                """,
+            marker = "(*Marker1*)",
+            list = ["PrivateField"; "PrivateMethod"; "PrivateType"])                 
+         
+    // Regression for bug 2116 -- Consider making selected item in completion list case-insensitiv         
+    [<Test>]
+    member this.``CaseInsensitive``() =
+        this.VerifyCtrlSpaceListContainAllAtStartOfMarker(
+            fileContents = """
+                type Test() =
+                    member this.Xyzzy = ()
+                    member this.xYzzy = ()
+                    member this.xyZzy = ()
+                    member this.xyzZy = ()
+                    member this.xyzzY = ()
+
+                let t = new Test()
+                t.XYZ(*Marker1*)
+                """,
+            marker = "(*Marker1*)",
+            list = ["Xyzzy"; "xYzzy"; "xyZzy"; "xyzZy"; "xyzzY"])  
+      
+    [<Test>]
+    member this.``Attributes.CanSeeOpenNamespaces.Bug268290.Case1``() =
+        AssertCtrlSpaceCompleteContains 
+            ["""
+                    module Foo
+                    open System
+                    [<
+             """]
+            "[<"
+            ["AttributeUsageAttribute"]
+            []
+      
+    [<Test>]
+    member this.``Attributes.CanSeeOpenNamespaces.Bug268290.Case2``() =
+        AssertCtrlSpaceCompleteContains 
+            ["""
+                    open System
+                    [<
+             """]
+            "[<"
+            ["AttributeUsageAttribute"]
+            []
+
+    [<Test>]
+    member this.``Selection``() =
+        AssertCtrlSpaceCompleteContains 
+            ["""
+                let preSelectedItem = 1
+                let r = (*MarkerPreSelectedItem*)pre
+                """]
+            "(*MarkerPreSelectedItem*)pre"
+            ["preSelectedItem"]
+            []
+            
+    // Regression test for 1653 -- Both the F# exception and the .NET exception representing it are shown in completion lists
+    [<Test>]
+    member this.``NoDupException.Postive``() = 
+        this.VerifyCtrlSpaceListContainAllAtStartOfMarker(
+            fileContents = """
+                let x = Match(*MarkerException*)""",
+            marker = "(*MarkerException*)",
+            list = ["MatchFailureException"])
+
+    [<Test>]
+    member this.``DotNetException.Negative``() =
+        this.VerifyCtrlSpaceListDoesNotContainAnyAtStartOfMarker(
+            fileContents = """
+                let x = Match(*MarkerException*)""",
+            marker = "(*MarkerException*)",
+            list = ["MatchFailure"])        
+
+    // Regression for bug 921 -- intellisense case-insensitive? 
+    [<Test>]
+    member this.``CaseInsensitive.MapMethod``() =
+        this.VerifyCtrlSpaceListContainAllAtStartOfMarker(
+            fileContents = """
+                List.MaP(*MarkerCase*)
+                """,
+            marker = "(*MarkerCase*)",
+            list = ["map"])
+                        
+    //Regression for bug   69644    69654  Fsharp: no completion for an identifier when 'use'd inside an 'async' block
+    [<Test>]
+    [<Ignore("69644 - no completion for an identifier when 'use'd inside an 'async' block")>]
+    member this.``InAsyncAndUseBlock``() =
+        this.VerifyCompListContainAllAtStartOfMarker(
+            fileContents = """
+                open System.Text.RegularExpressions
+                open System.IO
+
+                let collectLinksAsync (url:string) : Async<string> =
+                    async { do printfn "requesting %s" url
+                            let! html = 
+                                async { use reader = new System.IO.StreamReader(new System.IO.FileStream("", FileMode.CreateNew)) 
+                                        do printfn "reading %s" url
+                                        return (*Marker1*)reader.ReadToEnd()  }  //<---- reader
+                            let links = "a"
+                            return links }
+                """,
+            marker = "(*Marker1*)",
+            list = ["reader"])  
+
+    [<Test>]
+    member this.``WithoutOpenNamespace``() =
+        AssertCtrlSpaceCompleteContains 
+            ["""
+                module CodeAccessibility
+
+                let x = S(*Marker*)
+                """]
+            "(*Marker*)"
+            [] // should
+            ["Single"] // should not
+
+    [<Test>]
+    member this.``PrivateVisible``() =
+        AssertCtrlSpaceCompleteContains 
+            ["""
+                module CodeAccessibility
+
+                module Module1 =
+
+                    let private fieldPrivate = 1
+    
+                    let private MethodPrivate x = 
+                        x+1
+        
+                    type private TypePrivate() =
+                        member this.mem = 1
+    
+                    let a = (*Marker1*) 
+                    """]
+            "(*Marker1*) "
+            ["fieldPrivate";"MethodPrivate";"TypePrivate"]
+            []
+
+    [<Test>]
+    member this.``InternalVisible``() =
+        AssertCtrlSpaceCompleteContains 
+            ["""
+                module CodeAccessibility
+
+                module Module1 =
+
+                    let internal fieldInternal = 1
+    
+                    let internal MethodInternal x = 
+                        x+1
+        
+                    type internal TypeInternal() =
+                        member this.mem = 1
+    
+                    let a = (*Marker1*) """]
+            "(*Marker1*) "
+            ["fieldInternal";"MethodInternal";"TypeInternal"]  // should
+            [] // should not
+
+    [<Test>]
+    [<Category("Unit of Measure")>]
+    // Verify that we display the correct list of Unit of Measure (Names) in the autocomplete window. 
+    // This also ensures that no UoM are accidenatally added or removed.
+    member public this.``UnitMeasure.UnitNames``() =
+        AssertAutoCompleteContains
+          [ "Microsoft.FSharp.Data.UnitSystems.SI.UnitNames."]
+          "UnitNames."
+          [ "ampere"; "becquerel"; "candela"; "coulomb"; "farad"; "gray"; "henry"; "hertz";
+            "joule"; "katal"; "kelvin"; "kilogram"; "lumen"; "lux"; "metre"; "mole"; "newton";
+            "ohm"; "pascal"; "second"; "siemens"; "sievert"; "tesla"; "volt"; "watt"; "weber";] // should contain; exact match
+          [ ] // should not contain 
+
+    [<Test>]
+    [<Category("Unit of Measure")>]
+    // Verify that we display the correct list of Unit of Measure (Symbols) in the autocomplete window. 
+    // This also ensures that no UoM are accidenatally added or removed.
+    member public this.``UnitMeasure.UnitSymbols``() =
+        AssertAutoCompleteContains
+          [ "Microsoft.FSharp.Data.UnitSystems.SI.UnitSymbols."]
+          "UnitSymbols."
+          [ "A"; "Bq"; "C"; "F"; "Gy"; "H"; "Hz"; "J"; "K"; "N"; "Pa"; "S"; "Sv"; "T"; "V";
+            "W"; "Wb"; "cd"; "kat"; "kg"; "lm"; "lx"; "m"; "mol"; "ohm"; "s";] // should contain; exact match
+          [ ] // should not contain 
+
+(*------------------------------------------IDE Query automation start -------------------------------------------------*)
+    member private this.AssertAutoCompletionInQuery(fileContent : string list, marker:string,contained:string list) =
+        let file = createFile fileContent SourceFileKind.FS ["System.Xml.Linq"]
+            
+        let gpatcc = GlobalParseAndTypeCheckCounter.StartNew(this.VS)
+        MoveCursorToEndOfMarker(file, marker)
+        let completions = CompleteAtCursorForReason(file,Microsoft.VisualStudio.FSharp.LanguageService.BackgroundRequestReason.CompleteWord)
+        AssertCompListContainsAll(completions, contained)
+        gpatcc.AssertExactly(0,0)
+
+    [<Test>]
+    [<Category("Query")>]
+    // Custom operators appear in Intellisense list after entering a valid query operator
+    // on the previous line and invoking Intellisense manually
+    // Including in a nested query
+    member public this.``Query.Auto.InNestedQuery``() =
+        this.AssertAutoCompletionInQuery(
+          fileContent =["""
+            let tuples = [ (1, 8, 9); (56, 45, 3)] 
+            let numbers = [ 1;2; 8; 9; 15; 23; 3; 42; 4;0; 55;]
+
+            let foo = 
+                query {
+                    for n in numbers do
+                    let maxNumber = query {for x in tuples do ma}
+                    select n }"""],
+          marker = "do ma",
+          contained = [ "maxBy"; "maxByNullable"; ])
+
+    [<Test>]
+    [<Category("Query")>]
+    // Custom operators appear in Intellisense list after entering a valid query operator
+    // on the previous line and invoking Intellisense manually
+    // Including in a nested query
+    member public this.``Query.Auto.OffSetFromPreviousLine``() =
+        this.AssertAutoCompletionInQuery(
+          fileContent =["""
+            let numbers = [ 1;2; 8; 9; 15; 23; 3; 42; 4;0; 55;]
+            let foo = 
+                query {
+                    for n in numbers do
+                        gro
+                  }"""],
+          marker = "gro",
+          contained = [ "groupBy"; "groupJoin"; "groupValBy";])
+
+//****************************************//
+type DotCompletionListTests()  = 
+    inherit LanguageServiceBaseTests()
+
+   /////Helper Functios 
+        //DotCompList ContainAll At End Of Marker Helper Function
+    member private this.VerifyDotCompListContainAllAtEndOfMarker(fileContents : string, marker : string, list : string list) =
+        let (solution, project, file) = this.CreateSingleFileProject(fileContents)
+        let completions = DotCompletionAtEndOfMarker file marker
+        AssertCompListContainsAll(completions, list)
+    
+        //DotCompList ContainAll methods and properties At Start Of Marker Helper Function
+    member private this.VerifyDotCompListContainAllAtStartOfMarker(fileContents : string, marker : string, list :string list, ?addtlRefAssy : list<string>, ?coffeeBreak:bool) =
+        let (solution, project, file) = this.CreateSingleFileProject(fileContents, ?references = addtlRefAssy)
+        if defaultArg coffeeBreak false then TakeCoffeeBreak(this.VS)
+        let completions = DotCompletionAtStartOfMarker file marker
+        AssertCompListContainsAll(completions, list)
+
+        //DoesNotContainAny At Start Of Marker Helper Function 
+    member private this.VerifyDotCompListDoesNotContainAnyAtStartOfMarker(fileContents : string, marker : string, list : string list, ?addtlRefAssy : list<string>) =
+        let (solution, project, file) = this.CreateSingleFileProject(fileContents, ?references = addtlRefAssy)
+
+        let completions = DotCompletionAtStartOfMarker file marker
+        AssertCompListDoesNotContainAny(completions, list)
+  
+        //DotCompList Is Empty At Start Of Marker Helper Function
+    member private this.VerifyDotCompListIsEmptyAtStartOfMarker(fileContents : string, marker : string, ?addtlRefAssy : list<string>) =
+        let (solution, project, file) = this.CreateSingleFileProject(fileContents, ?references = addtlRefAssy)
+
+        let completions = DotCompletionAtStartOfMarker file marker
+        AssertCompListIsEmpty(completions)  
+               
+    [<Test>]
+    member this.``Namespace.System``() =
+        this.VerifyDotCompListContainAllAtEndOfMarker(
+            fileContents = """
+                // Test '.' after System
+                open System
+                let str = "a string"
+                // Test '.' after str
+                let _ = str(*usage*)
+                """,
+            marker = "open System",
+            list = [ "IO"; "Collections" ]) 
+                    
+    [<Test>]
+    member this.``Identifier.String.Positive``() = 
+        this.VerifyDotCompListContainAllAtStartOfMarker(
+            fileContents = """
+                open System
+                let str = "a string"
+                // Test '.' after str
+                let _ = str(*usage*)
+                """,
+            marker = "(*usage*)",
+            list = ["Chars"; "ToString"; "Length"; "GetHashCode"])   
+            
+    [<Test>]
+    member this.``Idenfifier.String.Negative``() =
+        this.VerifyDotCompListDoesNotContainAnyAtStartOfMarker(
+            fileContents = """
+                open System
+                let str = "a string"
+                // Test '.' after str
+                let _ = str(*usage*)
+                """,
+            marker = "(*usage*)",
+            list = ["Parse"; "op_Addition"; "op_Subtraction"])   
+
+    // Verify add_* methods show up for non-standard events. These are events
+    // where the associated delegate type does not return "void" 
+    [<Test>]
+    member this.``Event.NonStandard.PrefixMethods``() =
+        this.VerifyDotCompListContainAllAtStartOfMarker(
+            fileContents = """System.AppDomain.CurrentDomain(*usage*)""",
+            marker = "(*usage*)",
+            list = ["add_AssemblyResolve"; "remove_AssemblyResolve"; "add_ReflectionOnlyAssemblyResolve"; "remove_ReflectionOnlyAssemblyResolve"; "add_ResourceResolve"; "remove_ResourceResolve"; "add_TypeResolve"; "remove_TypeResolve"])           
+        
+    // Verify the events do show up. An error is generated when they are used asking the user to use add_* and remove_* instead.
+    // That is, they are legitimate name resolutions but do not pass type checking.
+    [<Test>]
+    member this.``Event.NonStandard.VerifyLegitimateNameShowUp``() = 
+        this.VerifyDotCompListContainAllAtStartOfMarker(
+            fileContents = "System.AppDomain.CurrentDomain(*usage*)",
+            marker = "(*usage*)",
+            list = ["AssemblyResolve"; "ReflectionOnlyAssemblyResolve"; "ResourceResolve"; "TypeResolve" ])
+
+    [<Test>]
+    member this.``Array``() = 
+        this.VerifyDotCompListContainAllAtStartOfMarker(
+            fileContents = "let arr = [| for i in 1..10 -> i |](*Mexparray*)",
+            marker = "(*Mexparray*)",
+            list = ["Clone"; "IsFixedSize"]) 
+        
+    [<Test>]
+    member this.``List``() = 
+        this.VerifyDotCompListContainAllAtStartOfMarker(
+            fileContents = "let lst = [ for i in 1..10 -> i](*Mexplist*)",
+            marker = "(*Mexplist*)",
+            list = ["Head"; "Tail"]) 
+
+    [<Test;Category("Repro")>]
+    member public this.``ExpressionDotting.Regression.Bug187799``() = 
+        this.VerifyDotCompListContainAllAtStartOfMarker(
+            fileContents = """
+                type T() = 
+                    member __.P with get() = new T()
+                    member __.M() = [|1..2|]
+                let t = new T()
+                t.P.M()(*marker*)  """,
+            marker = "(*marker*)",
+            list = ["Clone"])  // should contain method on array (result of M call)
+
+    [<Test;Category("Repro")>]
+    member public this.``ExpressionDotting.Regression.Bug187799.Test2``() = 
+        this.VerifyDotCompListContainAllAtStartOfMarker(
+            fileContents = """
+                type T() = 
+                    member __.M() = [|1..2|]
+
+                type R = { P : T } 
+                    
+                // dotting through an F# record field
+                let r = { P = T() }
+                r.P.M()(*marker*)  """,
+            marker = "(*marker*)",
+            list = ["Clone"])  // should contain method on array (result of M call)
+
+    [<Test;Category("Repro")>]
+    member public this.``ExpressionDotting.Regression.Bug187799.Test3``() = 
+        this.VerifyDotCompListContainAllAtStartOfMarker(
+            fileContents = """
+                type R = { P : System.Reflection.InterfaceMapping  } 
+                    
+                // Dotting through an F# record field and an IL record field
+                // Note that InterfaceMapping is a rare example of a public .NET instance field in mscorlib
+                let r = { P = Unchecked.defaultof<System.Reflection.InterfaceMapping > }
+                r.P(*marker*)""",
+            marker = "(*marker*)",
+            list = ["InterfaceMethods"])  
+
+
+
+    [<Test;Category("Repro")>]
+    member public this.``ExpressionDotting.Regression.Bug187799.Test4``() = 
+        this.VerifyDotCompListContainAllAtStartOfMarker(
+            fileContents = """
+                type R = { P : System.Reflection.InterfaceMapping  } 
+                    
+                // Dotting through an F# record field and an IL record field
+                // Note that InterfaceMapping is a rare example of a public .NET instance field in mscorlib
+                let f() = { P = Unchecked.defaultof<System.Reflection.InterfaceMapping > }
+                f().P(*marker*)""",
+            marker = "(*marker*)",
+            list = ["InterfaceMethods"])  
+
+    [<Test;Category("Repro")>]
+    member public this.``ExpressionDotting.Regression.Bug187799.Test5``() = 
+        this.VerifyDotCompListContainAllAtStartOfMarker(
+            fileContents = """
+                type R = { P : System.Reflection.InterfaceMapping  } 
+                    
+                // Note that InterfaceMapping is a rare example of a public .NET instance field in mscorlib
+                let f() = { P = Unchecked.defaultof<System.Reflection.InterfaceMapping > }
+                f().P.InterfaceMethods(*marker*)""",
+            marker = "(*marker*)",
+            list = ["GetEnumerator"])  
+
+    [<Test;Category("Repro")>]
+    member public this.``ExpressionDotting.Regression.Bug187799.Test6``() = 
+        this.VerifyDotCompListContainAllAtStartOfMarker(
+            fileContents = """
+                type R = { P : System.AppDomain  } 
+                    
+                // Test dotting through an F# record field and a .NET event
+                let f() = { P = null }
+                f().P.UnhandledException(*marker*)""",
+            marker = "(*marker*)",
+            list = ["AddHandler"])  
+
+    [<Test;Category("Repro")>]
+    member public this.``ExpressionDotting.Regression.Bug187799.Test7``() = 
+        this.VerifyDotCompListContainAllAtStartOfMarker(
+            fileContents = """
+                type R = { P : System.AppDomain  } 
+                    
+                // Test dotting through an F# record field and a .NET event
+                let f() = { P = null }
+                f().P.UnhandledException.GetType()(*marker*)""",
+            marker = "(*marker*)",
+            list = ["Assembly"])  
+
+    [<Test;Category("Repro")>]
+    member public this.``ExpressionDotting.Regression.Bug187799.Test8``() = 
+        this.VerifyDotCompListContainAllAtStartOfMarker(
+            fileContents = """
+                type C() =
+                    static member XXX with get() = 4 and set(x) = ()
+                    static member CCC with get() = C()
+
+                C.XXX(*marker*) <- 42""",
+            marker = "(*marker*)",
+            list = ["CompareTo"])  
+
+
+    [<Test;Category("Repro")>]
+    member public this.``ExpressionDotting.Regression.Bug187799.Test9``() = 
+        this.VerifyDotCompListContainAllAtStartOfMarker(
+            fileContents = """
+                type C() =
+                    static member XXX with get() = 4 and set(x) = ()
+                    static member CCC with get() = C()
+
+                C.XXX(*marker*) <- 42""",
+            marker = "(*marker*)",
+            list = ["CompareTo"])  
+
+    [<Test>]
+    [<Category("TypeProvider")>]
+    [<Category("TypeProvider.EditorHideMethodsAttribute")>]
+    // This test case checks that autocomplete on the provided Type DOES NOT show System.Object members
+    member this.``TypeProvider.EditorHideMethodsAttribute.Type.DoesnotContain``() =
+        this.VerifyDotCompListDoesNotContainAnyAtStartOfMarker(
+            fileContents = """ 
+                                let t = new N.T()
+                                t(*Marker*)""",
+            marker = "(*Marker*)",
+            list = ["Equals";"GetHashCode"],            
+            addtlRefAssy = [System.IO.Path.Combine(System.Environment.CurrentDirectory, @"UnitTestsResources\MockTypeProviders\EditorHideMethodsAttribute.dll")])
+
+    [<Test>]
+    [<Category("TypeProvider")>]
+    [<Category("TypeProvider.EditorHideMethodsAttribute")>]
+    // This test case checks if autocomplete on the provided Type shows only the Event1 elements
+    member this.``TypeProvider.EditorHideMethodsAttribute.Type.Contains``() =
+        this.VerifyDotCompListContainAllAtStartOfMarker(
+            fileContents = """ 
+                                let t = new N.T()
+                                t(*Marker*)""",
+            marker = "(*Marker*)",
+            list = ["Event1"],            
+            addtlRefAssy = [System.IO.Path.Combine(System.Environment.CurrentDirectory, @"UnitTestsResources\MockTypeProviders\EditorHideMethodsAttribute.dll")])
+    
+    [<Test>]
+    [<Category("TypeProvider")>]
+    [<Category("TypeProvider.EditorHideMethodsAttribute")>]
+    // This test case checks if autocomplete on the provided Type shows the instance method IM1
+    member this.``TypeProvider.EditorHideMethodsAttribute.InstanceMethod.Contains``() =
+        this.VerifyDotCompListContainAllAtStartOfMarker(
+            fileContents = """ 
+                                let t = new N1.T1()
+                                t(*Marker*)""",
+            marker = "(*Marker*)",
+            list = ["IM1"],            
+            addtlRefAssy = [System.IO.Path.Combine(System.Environment.CurrentDirectory, @"UnitTestsResources\MockTypeProviders\DummyProviderForLanguageServiceTesting.dll")])
+    
+    [<Test>]
+    [<Category("TypeProvider")>]
+    // This test case checks that nested types show up only statically and not on instances
+    member this.``TypeProvider.TypeContainsNestedType``() =
+        // should have it here
+        this.VerifyDotCompListContainAllAtStartOfMarker(
+            fileContents = """ 
+                                type XXX = N1.T1(*Marker*)""",
+            marker = "(*Marker*)",
+            list = ["SomeNestedType"],            
+            addtlRefAssy = [System.IO.Path.Combine(System.Environment.CurrentDirectory, @"UnitTestsResources\MockTypeProviders\DummyProviderForLanguageServiceTesting.dll")])
+        // should _not_ have it here
+        this.VerifyDotCompListDoesNotContainAnyAtStartOfMarker(
+            fileContents = """ 
+                                let t = new N1.T1()
+                                t(*Marker*)""",
+            marker = "(*Marker*)",
+            list = ["SomeNestedType"],            
+            addtlRefAssy = [System.IO.Path.Combine(System.Environment.CurrentDirectory, @"UnitTestsResources\MockTypeProviders\DummyProviderForLanguageServiceTesting.dll")])
+    
+    [<Test>]
+    [<Category("TypeProvider")>]
+    [<Category("TypeProvider.EditorHideMethodsAttribute")>]
+    // This test case checks if autocomplete on the provided Event shows only the AddHandler/RemoveHandler elements
+    member this.``TypeProvider.EditorHideMethodsAttribute.Event.Contain``() =
+        this.VerifyDotCompListContainAllAtStartOfMarker(
+            fileContents = """ 
+                                let t = new N.T()
+                                t.Event1(*Marker*)""",
+            marker = "(*Marker*)",
+            list = ["AddHandler";"RemoveHandler"],            
+            addtlRefAssy = [System.IO.Path.Combine(System.Environment.CurrentDirectory, @"UnitTestsResources\MockTypeProviders\EditorHideMethodsAttribute.dll")])
+    
+    [<Test>]
+    [<Category("TypeProvider")>]
+    [<Category("TypeProvider.EditorHideMethodsAttribute")>]
+    // This test case checks if autocomplete on the provided Method shows no elements 
+    // You can see this as a "negative case" (to check that the usage of the attribute on a method is harmless)
+    member this.``TypeProvider.EditorHideMethodsAttribute.Method.Contain``() =
+        this.VerifyDotCompListIsEmptyAtStartOfMarker(
+            fileContents = """ 
+                                let t = N.T.M(*Marker*)()""",
+            marker = "(*Marker*)",
+            addtlRefAssy = [System.IO.Path.Combine(System.Environment.CurrentDirectory, @"UnitTestsResources\MockTypeProviders\EditorHideMethodsAttribute.dll")])
+
+    [<Test>]
+    [<Category("TypeProvider")>]
+    [<Category("TypeProvider.EditorHideMethodsAttribute")>]
+    // This test case checks if autocomplete on the provided Property (the type of which is not synthetic) shows the usual elements... like GetType()
+    // 1. I think it does not make sense to use this attribute on a synthetic property unless it's type is also synthetic (already covered)
+    // 2. You can see this as a "negative case" (to check that the usage of the attribute is harmless)
+    member this.``TypeProvider.EditorHideMethodsAttribute.Property.Contain``() =
+        this.VerifyDotCompListContainAllAtStartOfMarker(
+            fileContents = """ 
+                                let t = N.T.StaticProp(*Marker*)""",
+            marker = "(*Marker*)",
+            list = ["GetType"; "Equals"],   // just a couple of System.Object methods: we expect them to be there!
+            addtlRefAssy = [System.IO.Path.Combine(System.Environment.CurrentDirectory, @"UnitTestsResources\MockTypeProviders\EditorHideMethodsAttribute.dll")])
+                                          
+    [<Test>]
+    member this.CompListInDiffFileTypes() =
+        let fileContents = """
+            val x:int = 1
+            x(*MarkerInsideaSignatureFile*)
+            """
+        let (solution, project, openfile) = this.CreateSingleFileProject(fileContents, fileKind = SourceFileKind.FSI)
+
+        let completions = DotCompletionAtStartOfMarker openfile "(*MarkerInsideaSignatureFile*)"
+        AssertCompListContainsAll(completions, []) // .fsi will not contain completions for this (it doesn't make sense)
+        
+        let fileContents = """
+            let i = 1
+            i(*MarkerInsideSourceFile*)
+            """
+        let (solution, project, file) = this.CreateSingleFileProject(fileContents)
+        
+        let completions = DotCompletionAtStartOfMarker file "(*MarkerInsideSourceFile*)"
+        AssertCompListContainsAll(completions, ["CompareTo"; "Equals"])
+  
+    [<Test>]
+    member this.ConstrainedTypes() =
+        let fileContents = """
+            type Pet() = 
+                member x.Name() = "pet"
+                member x.Speak() = "this is a pet"    
+            type Dog() = 
+                inherit Pet()
+                member x.dog() = "this is a dog"    
+            let dog = new Dog()
+            let pet = dog :> Pet
+            pet(*Mupcast*)
+            let dctest = pet :?> Dog
+            dctest(*Mdowncast*)
+            let f (x : bigint) = x(*Mconstrainedtoint*)
+            """
+        let references = 
+            [
+                "System.Numerics"  // code uses bigint
+            ]
+        let (solution, project, file) = this.CreateSingleFileProject(fileContents, references = references)        
+        let completions = DotCompletionAtStartOfMarker file "(*Mupcast*)"
+        AssertCompListContainsAll(completions, ["Name"; "Speak"])
+        
+        let completions = DotCompletionAtStartOfMarker file "(*Mdowncast*)"
+        AssertCompListContainsAll(completions, ["dog"; "Name"])
+        
+        let completions = DotCompletionAtStartOfMarker file "(*Mconstrainedtoint*)"
+        AssertCompListContainsAll(completions, ["ToString"])    
+
+    [<Test>]
+    [<Ignore("TODO tao test refactor")>]
+    member this.InternalNotVisibleInDiffAssembly() =
+        let fileContents = """
+            module CodeAccessibility
+            let type1 = new InternalNotVisibleInDiffAssembly.Module1.Type1()
+            type1(*MarkerDiffAssmb*)"""
+        let (solution, project, file) = this.CreateSingleFileProject(fileContents, references = ["InternalNotVisibleDiffAssembly.Assembly.dll"])
+
+        let completions = DotCompletionAtStartOfMarker file "(*MarkerDiffAssmb*)"
+        AssertCompListDoesNotContainAny(completions, ["fieldInternal";"MethodInternal"])
+
+    [<Test>]
+    member this.``Literal.Float``() = 
+        this.VerifyDotCompListContainAllAtStartOfMarker(
+            fileContents = "let myfloat = (42.0)(*Mconstantfloat*)",
+            marker = "(*Mconstantfloat*)",
+            list = ["GetType"; "ToString"])
+            
+    [<Test>] 
+    member this.``Literal.String``() =
+        this.VerifyDotCompListContainAllAtStartOfMarker(
+            fileContents = """let name = "foo"(*Mconstantstring*)""",
+            marker = "(*Mconstantstring*)",
+            list = ["Chars"; "Clone"]) 
+            
+    [<Test>]
+    member this.``Literal.Int``() = 
+        this.VerifyDotCompListContainAllAtStartOfMarker(
+            fileContents = "let typeint = (10)(*Mint*)",
+            marker = "(*Mint*)",
+            list = ["GetType";"ToString"])
+
+    [<Test>]
+    member this.``Identifier.InLambdaExpression``() = 
+        this.VerifyDotCompListContainAllAtStartOfMarker(
+            fileContents = "let funcLambdaExp = fun (x:int)-> x(*MarkerinLambdaExp*)",
+            marker = "(*MarkerinLambdaExp*)",
+            list = ["ToString"; "Equals"])
+
+    [<Test>]
+    member this.``Identifier.InClass``() = 
+        this.VerifyDotCompListContainAllAtStartOfMarker(
+            fileContents = """
+                type ClassLetBindIn(x:int) = 
+                    let m_field = x(*MarkerLetBindinClass*) """,
+            marker = "(*MarkerLetBindinClass*)",
+            list = ["ToString"; "Equals"])
+
+    [<Test>]
+    member this.``Identifier.InNestedLetBind``() = 
+        this.VerifyDotCompListContainAllAtStartOfMarker(
+            fileContents = "
+let funcNestedLetBinding (x:int) = 
+    let funcNested (x:int) = x(*MarkerNestedLetBind*)
+    () 
+",
+            marker = "(*MarkerNestedLetBind*)",
+            list = ["ToString"; "Equals"]) 
+
+    [<Test>]
+    member this.``Identifier.InModule``() = 
+        this.VerifyDotCompListContainAllAtStartOfMarker(
+            fileContents = "
+module ModuleLetBindIn =
+    let f (x:int) = x(*MarkerLetBindinModule*)
+",
+            marker = "(*MarkerLetBindinModule*)",
+            list = ["ToString"; "Equals"])
+
+    [<Test>]
+    member this.``Identifier.InMatchStatement``() = 
+        this.VerifyDotCompListContainAllAtStartOfMarker(
+            fileContents = "
+let x = 1
+match x(*MarkerMatchStatement*) with
+    |1 -> 1*1
+    |2 -> 2*2
+
+",
+            marker = "(*MarkerMatchStatement*)",
+            list = ["ToString"; "Equals"]) 
+
+    [<Test>]
+    member this.``Identifier.InMatchClause``() = 
+        this.VerifyDotCompListContainAllAtStartOfMarker(
+            fileContents = "
+let rec f l = 
+    match l with
+    | [] ->
+        let xx = System.DateTime.Now
+        let y = xx(*MarkerMatchClause*)
+        ()
+    | x :: xs -> f xs
+",
+            marker = "(*MarkerMatchClause*)",
+            list = ["Add";"Date"]) 
+                           
+    [<Test>]
+    member this.``Expression.ListItem``() = 
+        this.VerifyDotCompListContainAllAtStartOfMarker(
+            fileContents = """
+                let a = [1;2;3]
+                a.[1](*MarkerListItem*)
+                """,
+            marker = "(*MarkerListItem*)",
+            list = ["CompareTo"; "ToString"])
+
+    [<Test>]
+    member this.``Expression.FunctionParameter``() = 
+        this.VerifyDotCompListContainAllAtStartOfMarker(
+            fileContents = """
+                let f (x : string) = ()
+                f ("1" + "1")(*MarkerParameter*)
+                """,
+            marker = "(*MarkerParameter*)",
+            list = ["CompareTo"; "ToString"])
+
+    [<Test>]
+    member this.``Expression.Function``() = 
+        this.VerifyDotCompListContainAllAtStartOfMarker(
+            fileContents = """
+                let func(mm) = 100
+                func(x + y)(*MarkerFunction*)
+                """,
+            marker = "(*MarkerFunction*)",
+            list = ["CompareTo"; "ToString"])
+
+    [<Test>]
+    member this.``Expression.RecordPattern``() = 
+        this.VerifyDotCompListContainAllAtStartOfMarker(
+            fileContents = """
+                type Rec = 
+                    { X : int} 
+                    member this.Value = 42
+                { X = 1 }(*MarkerRecordPattern*)
+                """,
+            marker = "(*MarkerRecordPattern*)",
+            list = ["Value"; "ToString"])
+
+    [<Test>]
+    member this.``Expression.2DArray``() = 
+        this.VerifyDotCompListContainAllAtStartOfMarker(
+            fileContents = """
+                let (a2: int[,]) = Array2.zero_create 10 10
+                a2.[1,2](*Marker2DArray*) 
+                """,
+            marker = "(*Marker2DArray*)",
+            list = ["ToString"]) 
+
+    [<Test>]
+    member this.``Expression.LetBind``() = 
+        this.VerifyDotCompListContainAllAtStartOfMarker(
+            fileContents = """
+                let f (x : string) = ()
+                //And in many different contexts where the ??tomic expression??occurs at the end of the expression, e.g.
+                let x = y in f ("1" + "1")(*MarkerContext1*)
+                """,
+            marker = "(*MarkerContext1*)",
+            list = ["CompareTo";"ToString"]) 
+
+    [<Test>]
+    member this.``Expression.WhileLoop``() = 
+        this.VerifyDotCompListContainAllAtStartOfMarker(
+            fileContents = """
+                let f (x : string) = ()
+                while true do
+                    f ("1" + "1")(*MarkerContext3*) 
+                """,
+            marker = "(*MarkerContext3*)",
+            list = ["CompareTo";"ToString"])  
+
+    [<Test>] 
+    member this.``Expression.List``() = 
+        this.VerifyDotCompListContainAllAtStartOfMarker(
+            fileContents = """[1;2](*MarkerList*)   """,
+            marker = "(*MarkerList*)",
+            list = ["Head"; "Item"])
+
+    [<Test>]
+    member this.``Expression.Nested.InLetBind``() = 
+        this.VerifyDotCompListContainAllAtStartOfMarker(
+            fileContents = """
+                let f (x : string) = ()
+                // Nested expressions
+                let x = 42 |> ignore; f ("1" + "1")(*MarkerNested1*)
+                """,
+            marker = "(*MarkerNested1*)",
+            list = ["Chars";"Length"])
+
+    [<Test>]
+    member this.``Expression.Nested.InWhileLoop``() = 
+        this.VerifyDotCompListContainAllAtStartOfMarker(
+            fileContents = """
+                let f (x : string) = ()
+                while true do
+                    ignore (f ("1" + "1")(*MarkerNested2*)) 
+                """,
+            marker = "(*MarkerNested2*)",
+            list = ["Chars";"Length"])  
+
+    [<Test>]
+    member this.``Expression.ArrayItem.Positive``() =
+        this.VerifyDotCompListContainAllAtStartOfMarker(
+            fileContents = """
+                //regression test for bug 1001
+                let str1 = Array.init 10 string
+                str1.[1](*MarkerArrayIndexer*)""",
+            marker = "(*MarkerArrayIndexer*)",
+            list = ["Chars";"Split"])
+
+    [<Test>]
+    member this.``Expression.ArrayItem.Negative``() =
+        this.VerifyDotCompListDoesNotContainAnyAtStartOfMarker(
+            fileContents = """
+                //regression test for bug 1001
+                let str1 = Array.init 10 string
+                str1.[1](*MarkerArrayIndexer*)""",
+            marker = "(*MarkerArrayIndexer*)",
+            list = ["IsReadOnly";"Rank"])
+                                                                                                                                                                
+    [<Test>]
+    member this.``ObjInstance.InheritedClass.MethodsDefInBase``() = 
+        this.VerifyDotCompListContainAllAtStartOfMarker(
+            fileContents = """
+                type Pet() = 
+                    member x.Name() = "pet"
+                    member x.Speak() = "this is a pet"    
+                type Dog() = 
+                    inherit Pet() 
+                    member x.dog() = "this is a dog"    
+                let dog = new Dog()
+                dog(*Mderived*)""",
+            marker = "(*Mderived*)",
+            list = ["Name"; "dog"])
+
+    [<Test>]
+    member this.``ObjInstance.AnonymousClass.MethodsDefInInterface``() =
+        this.VerifyDotCompListContainAllAtStartOfMarker(
+            fileContents = """
+                type IFoo =
+                    abstract DoStuff  : unit -> string
+                    abstract DoStuff2 : int * int -> string -> string
+                // Implement an interface in a class (This is kind of lame if you don�t want to actually declare a class)
+                type Foo() =
+                    interface IFoo with
+                        member this.DoStuff () = "Return a string"
+                        member this.DoStuff2 (x, y) z = sprintf "Arguments were (%d, %d) %s" x y z
+                // instanceOfIFoo is an instance of an anonomyous class which implements IFoo
+                let instanceOfIFoo = {
+                                        new IFoo with
+                                            member this.DoStuff () = "Implement IFoo"
+                                            member this.DoStuff2 (x, y) z = sprintf "Arguments were (%d, %d) %s" x y z
+                                     }(*Mexpnewtype*)""",
+            marker = "(*Mexpnewtype*)",
+            list = ["DoStuff"; "DoStuff2"])
+             
+    [<Test>]
+    member this.``SimpleTypes.SystemTime``() = 
+        this.VerifyDotCompListContainAllAtStartOfMarker(
+            fileContents = """
+                let typestruct = System.DateTime.Now
+                typestruct(*Mstruct*)""",
+            marker = "(*Mstruct*)",
+            list = ["AddDays"; "Date"])
+
+    [<Test>]
+    member this.``SimpleTypes.Record``() = 
+        this.VerifyDotCompListContainAllAtStartOfMarker(
+            fileContents = """
+                type Person = { Name: string; DateOfBirth: System.DateTime }
+                let typrecord = { Name = "Bill"; DateOfBirth = new System.DateTime(1962,09,02) }
+                typrecord(*Mrecord*)""",
+            marker = "(*Mrecord*)",
+            list = ["DateOfBirth"; "Name"]) 
+
+    [<Test>]
+    member this.``SimpleTypes.Enum``() = 
+        this.VerifyDotCompListContainAllAtStartOfMarker(
+            fileContents = """
+                type weekday = 
+                    | Monday = 1
+                    | Tuesday = 2
+                    | Wednesday = 3
+                    | Thursday = 4
+                    | Friday = 5
+                let typeenum = weekday.Friday
+                typeenum(*Menum*)""",
+            marker = "(*Menum*)",
+            list = ["GetType"; "ToString"])
+
+    [<Test>]
+    member this.``SimpleTypes.DisUnion``() = 
+        this.VerifyDotCompListContainAllAtStartOfMarker(
+            fileContents = """
+                type Route = int
+                type Make = string
+                type Model = string
+                type Transport =
+                    | Car of Make * Model
+                    | Bicycle
+                    | Bus of Route
+                let typediscriminatedunion = Car("BMW","360")
+                typediscriminatedunion(*Mdiscriminatedunion*)""",
+            marker = "(*Mdiscriminatedunion*)",
+            list = ["GetType"; "ToString"])  
+
+    [<Test>]
+    member this.``InheritedClass.BaseClassPrivateMethod.Negative``() =
+        this.VerifyDotCompListDoesNotContainAnyAtStartOfMarker(
+            fileContents = """
+                open System
+                //difine the base class
+                type Widget() = 
+                    let mutable state = 0 
+                    member internal x.MethodInternal() = state 
+                    member public x.MethodPublic(n) = state <- state + n
+                    member private x.MethodPrivate() = (state <> 0)
+                    [<DefaultValue>]
+                    val mutable internal fieldInternal:int 
+                    [<DefaultValue>]
+                    val mutable public fieldPublic:int
+                    [<DefaultValue>]
+                    val mutable private fieldPrivate:int 
+                //define the divided class which inherent "Widget"
+                type Divided() =
+                    inherit Widget() 
+                    member x.myPrint() = 
+                        base(*MUnShowPrivate*)         
+                Console.ReadKey(true)""" ,
+            marker = "(*MUnShowPrivate*)",
+            list = ["MethodPrivate";"fieldPrivate"]) 
+
+    [<Test>]
+    member this.``InheritedClass.BaseClassPublicMethodAndProperty``() =
+        this.VerifyDotCompListContainAllAtStartOfMarker(
+            fileContents = """
+                open System
+                //difine the base class
+                type Widget() = 
+                    let mutable state = 0 
+                    member internal x.MethodInternal() = state 
+                    member public x.MethodPublic(n) = state <- state + n
+                    member private x.MethodPrivate() = (state <> 0)
+                    [<DefaultValue>]
+                    val mutable internal fieldInternal:int 
+                    [<DefaultValue>]
+                    val mutable public fieldPublic:int
+                    [<DefaultValue>]
+                    val mutable private fieldPrivate:int   
+                //define the divided class which inherent "Widget"
+                type Divided() =
+                    inherit Widget() 
+                    member x.myPrint() = 
+                        base(*MShowPublic*) 
+                Console.ReadKey(true)""",
+            marker = "(*MShowPublic*)",
+            list = ["MethodPublic";"fieldPublic"])
+
+    [<Test>]
+    member this.``Visibility.InternalNestedClass.Negative``() =
+        this.VerifyDotCompListDoesNotContainAnyAtStartOfMarker(
+            fileContents = """System.Console(*Marker1*)""",
+            marker = "(*Marker1*)",
+            list = ["ControlCDelegateData"])
+
+    [<Test>]
+    member this.``Visibility.PrivateIdentifierInDiffModule.Negative``() = 
+        this.VerifyDotCompListIsEmptyAtStartOfMarker(
+            fileContents = """
+                module Module1 =
+                    let private fieldPrivate = 1    
+                    let private MethodPrivate x = 
+                        x+1    
+                    type private TypePrivate()=
+                        member this.mem = 1 
+                module Module2 =
+                    Module1(*Marker1*)  """,
+            marker = "(*Marker1*)")
+
+    [<Test>]
+    member this.``Visibility.PrivateIdentifierInDiffClass.Negative``() = 
+        this.VerifyDotCompListDoesNotContainAnyAtStartOfMarker(
+            fileContents = """
+                open System
+                module Module1 =
+                    type Type1()=           
+                        [<DefaultValue>]
+                        val mutable private fieldPrivate:int            
+                        member private x.MethodPrivate() = 1         
+                    type Type2()=
+                        let M1=        
+                        let type1 = new Type1()                
+                        type1(*MarkerOutType*) """,
+            marker = "(*MarkerOutType*)",
+            list = ["fieldPrivate";"MethodPrivate"]) 
+
+    [<Test>]
+    member this.``Visibility.PrivateFieldInSameClass``() =  
+        this.VerifyDotCompListContainAllAtStartOfMarker(
+            fileContents = """
+                open System
+
+                module Module1 =
+                    type Type1()=           
+                        [<DefaultValue>]
+                        val mutable private PrivateField:int            
+                        static member private PrivateMethod() = 1         
+                        member this.Field1 with get () = this(*MarkerFieldInType*)         
+                        member x.MethodTest() = Type1(*MarkerMethodInType*)         
+                    let type1 = new Type1() """,
+            marker = "(*MarkerFieldInType*)",
+            list = ["PrivateField"]) 
+
+    [<Test>]
+    member this.``Visibility.PrivateMethodInSameClass``() = 
+        this.VerifyDotCompListContainAllAtStartOfMarker(
+            fileContents = """
+                open System
+
+                module Module1 =
+                    type Type1()=           
+                        [<DefaultValue>]
+                        val mutable private PrivateField:int            
+                        static member private PrivateMethod() = 1         
+                        member this.Field1 with get () = this(*MarkerFieldInType*)         
+                        member x.MethodTest() = Type1(*MarkerMethodInType*)         
+                    let type1 = new Type1() """,
+            marker = "(*MarkerMethodInType*)",
+            list = ["PrivateMethod"])       
+
+    [<Test>]
+    member this.``VariableIdentifier.AsParameter``() =
+        this.VerifyDotCompListContainAllAtStartOfMarker(
+            fileContents = """
+                module MyModule =
+                    type DuType =
+                         | Tag of int         
+                    let f (DuType(*Maftervariable1*).Tag(x)) = 10 """,
+            marker = "(*Maftervariable1*)",
+            list = ["Tag"])
+
+    [<Test>]
+    member this.``VariableIdentifier.InMeasure.DefineInDiffNamespace``() = 
+        this.VerifyDotCompListContainAllAtStartOfMarker(
+            fileContents = """
+                namespace MyNamespace1
+                module MyModule =
+                    type DuType =
+                         | Tag of int         
+                    let f (DuType(*Maftervariable1*).Tag(x)) = 10 
+                    type Pet() = 
+                        member x.Name = "pet"
+                        member x.Speak() = "this is a pet"
+                    type Dog() = 
+                        inherit Pet()
+                        do base(*Maftervariable3*).GetType()
+                    let dog = new Dog()
+                namespace MyNamespace2
+                module MyModule2 = 
+                    let typeFunc<MyNamespace1.MyModule(*Maftervariable2*)> = [1; 2; 3]
+                    let f (x:MyNamespace1.MyModule(*Maftervariable4*)) = 10
+                    let y = int System.IO(*Maftervariable5*)""",
+            marker = "(*Maftervariable2*)",
+            list = ["DuType";"Tag"])
+
+    [<Test>]
+    member this.``VariableIdentifier.MethodsInheritFomeBase``() = 
+        this.VerifyDotCompListContainAllAtStartOfMarker(
+            fileContents = """
+                namespace MyNamespace1
+                module MyModule =
+                    type DuType =
+                         | Tag of int         
+                    let f (DuType(*Maftervariable1*).Tag(x)) = 10 
+                    type Pet() = 
+                        member x.Name = "pet"
+                        member x.Speak() = "this is a pet"
+                    type Dog() = 
+                        inherit Pet()
+                        do base(*Maftervariable3*).GetType()
+                    let dog = new Dog()""",
+            marker = "(*Maftervariable3*)",
+            list = ["Name";"Speak"])
+
+    [<Test>]
+    member this.``VariableIdentifier.AsParameter.DefineInDiffNamespace``() = 
+        this.VerifyDotCompListContainAllAtStartOfMarker(
+            fileContents = """
+                namespace MyNamespace1
+                module MyModule =
+                    type DuType =
+                         | Tag of int         
+                    let f (DuType(*Maftervariable1*).Tag(x)) = 10 
+                    type Pet() = 
+                        member x.Name = "pet"
+                        member x.Speak() = "this is a pet"
+                    type Dog() = 
+                        inherit Pet()
+                        do base(*Maftervariable3*).GetType()
+                    let dog = new Dog()
+                namespace MyNamespace2
+                module MyModule2 = 
+                    let typeFunc<MyNamespace1.MyModule(*Maftervariable2*)> = [1; 2; 3]
+                    let f (x:MyNamespace1.MyModule(*Maftervariable4*)) = 10
+                    let y = int System.IO(*Maftervariable5*)""",
+            marker = "(*Maftervariable4*)",
+            list = ["DuType";"Tag"])  
+
+    [<Test>]
+    member this.``VariableIdentifier.SystemNamespace``() = 
+        this.VerifyDotCompListContainAllAtStartOfMarker(
+            fileContents = """
+                namespace MyNamespace1
+                module MyModule =
+                    type DuType =
+                         | Tag of int         
+                    let f (DuType(*Maftervariable1*).Tag(x)) = 10 
+                    type Pet() = 
+                        member x.Name = "pet"
+                        member x.Speak() = "this is a pet"
+                    type Dog() = 
+                        inherit Pet()
+                        do base(*Maftervariable3*).GetType()
+                    let dog = new Dog()
+                namespace MyNamespace2
+                module MyModule2 = 
+                    let typeFunc<MyNamespace1.MyModule(*Maftervariable2*)> = [1; 2; 3]
+                    let f (x:MyNamespace1.MyModule(*Maftervariable4*)) = 10
+                    let y = int System.IO(*Maftervariable5*)""",
+            marker = "(*Maftervariable5*)",
+            list = ["BinaryReader";"Stream";"Directory"]) 
+
+    [<Test>]
+    member this.``LongIdent.AsAttribute``() = 
+        this.VerifyDotCompListContainAllAtStartOfMarker(
+            fileContents = """
+                [<System(*Mattribute*)>]
+                type TestAttribute() = 
+                    member x.print() = "print" """,
+            marker = "(*Mattribute*)",
+            list = ["Int32";"ObsoleteAttribute"])
+
+    [<Test>]
+    member this.``ImportStatment.System.ImportDirectly``() = 
+        this.VerifyDotCompListContainAllAtStartOfMarker(
+            fileContents = """
+                open System(*Mimportstatement1*)
+                open IO = System(*Mimportstatement2*)""",
+            marker = "(*Mimportstatement1*)",
+            list = ["Collections"])
+
+    [<Test>]
+    member this.``ImportStatment.System.ImportAsIdentifier``() = 
+        this.VerifyDotCompListContainAllAtStartOfMarker(
+            fileContents = """
+                open System(*Mimportstatement1*)
+                open IO = System(*Mimportstatement2*)""",
+            marker = "(*Mimportstatement2*)",
+            list = ["IO"])  
+
+    [<Test>]
+    member this.``LongIdent.PatternMatch.AsVariable.DefFromDiffNamespace``() =
+        this.VerifyDotCompListContainAllAtStartOfMarker(
+            fileContents = """
+                namespace NS
+                module longident =
+                    type Direction =
+                        | Left         = 1
+                        | Right        = 2
+                    type MoveCursor() = 
+                        member this.Direction = Direction.Left
+                namespace NS2       
+                module test =
+                    let cursor = new NS.longident.MoveCursor()
+                    match cursor(*Mpatternmatch1*) with
+                    | NS.longident.Direction.Left -> "move left"
+                    | NS(*Mpatternmatch2*) -> "move right" """,
+            marker = "(*Mpatternmatch1*)",
+            list = ["Direction";"ToString"])
+
+    [<Test>]
+    member this.``LongIdent.PatternMatch.AsConstantValue.DefFromDiffNamespace``() =
+        this.VerifyDotCompListContainAllAtStartOfMarker(
+            fileContents = """
+                namespace NS
+                module longident =
+                    type Direction =
+                        | Left         = 1
+                        | Right        = 2
+                    type MoveCursor() = 
+                        member this.Direction = Direction.Left
+                namespace NS2       
+                module test =
+                    let cursor = new NS.longident.MoveCursor()
+                    match cursor(*Mpatternmatch1*) with
+                    | NS.longident.Direction.Left -> "move left"
+                    | NS(*Mpatternmatch2*) -> "move right" """,
+            marker = "(*Mpatternmatch2*)",
+            list = ["longident"])
+
+    [<Test>]
+    member this.``LongIdent.PInvoke.AsReturnType``() = 
+        this.VerifyDotCompListContainAllAtStartOfMarker(
+            fileContents = """
+                open System.IO
+                open System.Runtime.InteropServices
+                // Get two temp files, write data into one of them
+                let tempFile1, tempFile2 = Path.GetTempFileName(), Path.GetTempFileName()
+                let writer = new StreamWriter (tempFile1)
+                writer.WriteLine("Some Data")
+                writer.Close()
+                // Origional signature
+                //[<DllImport("kernel32.dll")>]
+                //extern bool CopyFile(string lpExistingFileName, string lpNewFileName, bool bFailIfExists);
+                [<DllImport("kernel32.dll", EntryPoint="CopyFile")>]
+                extern System(*Mpinvokereturntype*) CopyFile_Arrays(char[] lpExistingFileName, char[] lpNewFileName, bool bFailIfExists);
+                let result = CopyFile_Arrays(tempFile1.ToCharArray(), tempFile2.ToCharArray(), false)
+                printfn "Array %A" result""",
+            marker = "(*Mpinvokereturntype*)",
+            list = ["Boolean";"Int32"])
+
+    [<Test>]
+    member this.``LongIdent.PInvoke.AsAttribute``() = 
+        this.VerifyDotCompListContainAllAtStartOfMarker(
+            fileContents = """
+                open System.IO
+                open System.Runtime.InteropServices
+
+                module mymodule = 
+                    type SomeAttrib() = 
+                        inherit System.Attribute() 
+                    type myclass() = 
+                        member x.name() = "test case"
+                module mymodule2 =    
+                    [<DllImport("kernel32.dll", EntryPoint="CopyFile")>]
+                    extern bool CopyFile_Attrib([<mymodule(*Mpinvokeattribute*)>] char [] lpExistingFileName, char []lpNewFileName, [<mymodule.SomeAttrib>] bool & bFailIfExists);
+
+                    let result5 = CopyFile_Arrays(tempFile1.ToCharArray(), tempFile2.ToCharArray(), false)
+                    printfn "WithAttribute %A" result5""",
+            marker = "(*Mpinvokeattribute*)",
+            list = ["SomeAttrib";"myclass"]) 
+
+    [<Test>]
+    member this.``LongIdent.PInvoke.AsParameterType``() = 
+        this.VerifyDotCompListContainAllAtStartOfMarker(
+            fileContents = """
+                open System.IO
+                open System.Runtime.InteropServices
+                [<DllImport("kernel32.dll", EntryPoint="CopyFile")>]
+                extern bool CopyFile_ArraySpaces(char [] lpExistingFileName, char []lpNewFileName, System(*Mpinvokeparametertype*) bFailIfExists);
+                let result2 = CopyFile_Arrays(tempFile1.ToCharArray(), tempFile2.ToCharArray(), false)
+                printfn "Array Space %A" result2""",
+            marker = "(*Mpinvokeparametertype*)",
+            list = ["Boolean";"Int32"])
+
+    [<Test>]
+    member this.``LongIdent.Record.AsField``() = 
+        this.VerifyDotCompListContainAllAtStartOfMarker(
+            fileContents = """
+                module MyModule =
+                    type person =
+                        { name: string;
+                        dateOfBirth: System.DateTime; }
+                module MyModule2 =     
+                    let x = {MyModule(*Mrecord*) = 32}""",
+            marker = "(*Mrecord*)",
+            list = ["person"])   
+
+    [<Test>]
+    member this.``LongIdent.DiscUnion.AsTypeParameter.DefInDiffNamespace``() =
+        this.VerifyDotCompListContainAllAtStartOfMarker(
+            fileContents = """
+                namespace MyNamespace1
+                module MyModule =
+                    type DuType =
+                         | Tag of int          
+                    type Pet() = 
+                        member x.Name = "pet"
+                        member x.Speak() = "this is a pet"  
+                    type Dog() = 
+                        inherit Pet() 
+                namespace MyNamespace2
+                module MyModule2 =     
+                    let foo = MyNamespace1.MyModule(*Mtypeparameter1*)
+                    let f (x:int) = MyNamespace1.MyModule.DuType(*Mtypeparameter2*)    
+                    let typeFunc<MyNamespace1.MyModule(*Mtypeparameter3*)> = 10""",
+            marker = "(*Mtypeparameter1*)",
+            list = ["Dog";"DuType"])
+
+    [<Test>]
+    member this.``LongIdent.AnonymousFunction.AsTypeParameter.DefFromDiffNamespace``() = 
+        this.VerifyDotCompListContainAllAtStartOfMarker(
+            fileContents = """
+                namespace MyNamespace1
+                module MyModule =
+                    type DuType =
+                         | Tag of int          
+                    type Pet() = 
+                        member x.Name = "pet"
+                        member x.Speak() = "this is a pet"  
+                    type Dog() = 
+                        inherit Pet() 
+                namespace MyNamespace2
+                module MyModule2 =     
+                    let foo = MyNamespace1.MyModule(*Mtypeparameter1*)
+                    let f (x:int) = MyNamespace1.MyModule.DuType(*Mtypeparameter2*)    
+                    let typeFunc<MyNamespace1.MyModule(*Mtypeparameter3*)> = 10""",
+            marker = "(*Mtypeparameter2*)",
+            list = ["Tag"])
+
+    [<Test>]
+    member this.``LongIdent.UnitMeasure.AsTypeParameter.DefFromDiffNamespace``() = 
+        this.VerifyDotCompListContainAllAtStartOfMarker(
+            fileContents = """
+                namespace MyNamespace1
+                module MyModule =
+                    type DuType =
+                         | Tag of int          
+                    type Pet() = 
+                        member x.Name = "pet"
+                        member x.Speak() = "this is a pet"  
+                    type Dog() = 
+                        inherit Pet() 
+                namespace MyNamespace2
+                module MyModule2 =     
+                    let foo = MyNamespace1.MyModule(*Mtypeparameter1*)
+                    let f (x:int) = MyNamespace1.MyModule.DuType(*Mtypeparameter2*)    
+                    let typeFunc<MyNamespace1.MyModule(*Mtypeparameter3*)> = 10""",
+            marker = "(*Mtypeparameter3*)",
+            list = ["Dog";"DuType"])
+
+    [<Test>]
+    member this.``RedefinedIdentifier.DiffScope.InScope.Positive``() =
+        this.VerifyDotCompListContainAllAtStartOfMarker(
+            fileContents = """
+                let identifierBothScope = ""
+                let functionScope () =
+                    let identifierBothScope = System.DateTime.Now
+                    identifierBothScope(*MarkerShowLastOneWhenInScope*)
+                identifierBothScope(*MarkerShowLastOneWhenOutscoped*)""",
+            marker = "(*MarkerShowLastOneWhenInScope*)",
+            list = ["DayOfWeek"])  
+
+    [<Test>]
+    member this.``RedefinedIdentifier.DiffScope.InScope.Negative``() =
+        this.VerifyDotCompListDoesNotContainAnyAtStartOfMarker(
+            fileContents = """
+                let identifierBothScope = ""
+                let functionScope () =
+                    let identifierBothScope = System.DateTime.Now
+                    identifierBothScope(*MarkerShowLastOneWhenInScope*)
+                identifierBothScope(*MarkerShowLastOneWhenOutscoped*)""",
+            marker = "(*MarkerShowLastOneWhenInScope*)",
+            list = ["Chars"]) 
+
+    [<Test>]
+    member this.``RedefinedIdentifier.DiffScope.OutScope.Positive``() =
+        this.VerifyDotCompListContainAllAtStartOfMarker(
+            fileContents = """
+                let identifierBothScope = ""
+                let functionScope () =
+                    let identifierBothScope = System.DateTime.Now
+                    identifierBothScope(*MarkerShowLastOneWhenInScope*)
+                identifierBothScope(*MarkerShowLastOneWhenOutscoped*)""",
+            marker = "(*MarkerShowLastOneWhenOutscoped*)",
+            list = ["Chars"])
+
+    [<Test>]
+    member this.``ObjInstance.ExtensionMethods.WithoutDef.Negative``() =
+        this.VerifyDotCompListDoesNotContainAnyAtStartOfMarker(
+            fileContents = """
+                open System
+                let rnd = new System.Random()
+                rnd(*MWithoutReference*)""",
+            marker = "(*MWithoutReference*)",
+            list = ["NextDice";"DiceValue"])
+
+    [<Test>]
+    member this.``Class.DefInDiffNameSpace``() = 
+        this.VerifyDotCompListContainAllAtStartOfMarker(
+            fileContents = """
+                namespace NS1
+                module  MyModule =
+                    [<System.ObsoleteAttribute>]
+                    type ObsoleteType() = 
+                        member this.TestMethod() = 10        
+                    [<CompilerMessage("This construct is for ML compatibility.", 62, IsHidden=true)>]
+                    type CompilerMesageType() = 
+                        member this.TestMethod() = 10
+                    type TestType() = 
+                        member this.TestMethod() = 100
+                        [<System.ObsoleteAttribute>]
+                        member this.ObsoleteMethod() = 100
+                        [<CompilerMessage("This construct is for ML compatibility.", 62, IsHidden=true)>]
+                        member this.CompilerMesageMethod() = 100
+                        [<CompilerMessage("This construct is hidden", 1023, IsHidden=true)>]
+                        member this.HiddenMethod() = 10
+                        [<CompilerMessage("This construct is not hidden", 1023, IsHidden=false)>]
+                        member this.VisibleMethod() = 10
+                        [<CompilerMessage("This construct is not hidden", 1023)>]
+                        member this.VisibleMethod2() = 10
+                namespace NS2
+                module m2 =
+                    type x = NS1.MyModule(*MarkerType*)
+                    let b = (new NS1.MyModule.TestType())(*MarkerMethod*)
+                """,
+            marker = "(*MarkerType*)" ,
+            list = ["TestType"])
+
+    [<Test>]
+    member this.``Class.DefInDiffNameSpace.WithAttributes.Negative``() = 
+        this.VerifyDotCompListDoesNotContainAnyAtStartOfMarker(
+            fileContents = """
+                namespace NS1
+                module  MyModule =
+                    [<System.ObsoleteAttribute>]
+                    type ObsoleteType() = 
+                        member this.TestMethod() = 10        
+                    [<CompilerMessage("This construct is for ML compatibility.", 62, IsHidden=true)>]
+                    type CompilerMesageType() = 
+                        member this.TestMethod() = 10
+                    type TestType() = 
+                        member this.TestMethod() = 100
+                        [<System.ObsoleteAttribute>]
+                        member this.ObsoleteMethod() = 100
+                        [<CompilerMessage("This construct is for ML compatibility.", 62, IsHidden=true)>]
+                        member this.CompilerMesageMethod() = 100
+                        [<CompilerMessage("This construct is hidden", 1023, IsHidden=true)>]
+                        member this.HiddenMethod() = 10
+                        [<CompilerMessage("This construct is not hidden", 1023, IsHidden=false)>]
+                        member this.VisibleMethod() = 10
+                        [<CompilerMessage("This construct is not hidden", 1023)>]
+                        member this.VisibleMethod2() = 10
+                namespace NS2
+                module m2 =
+                    type x = NS1.MyModule(*MarkerType*)
+                    let b = (new NS1.MyModule.TestType())(*MarkerMethod*)
+                """,
+            marker = "(*MarkerType*)",
+            list = ["ObsoleteType";"CompilerMesageType"])
+
+    [<Test>]
+    member this.``Method.DefInDiffNameSpace``() =
+        this.VerifyDotCompListContainAllAtStartOfMarker(
+            fileContents = """
+                namespace NS1
+                module  MyModule =
+                    [<System.ObsoleteAttribute>]
+                    type ObsoleteType() = 
+                        member this.TestMethod() = 10        
+                    [<CompilerMessage("This construct is for ML compatibility.", 62, IsHidden=true)>]
+                    type CompilerMesageType() = 
+                        member this.TestMethod() = 10
+                    type TestType() = 
+                        member this.TestMethod() = 100
+                        [<System.ObsoleteAttribute>]
+                        member this.ObsoleteMethod() = 100
+                        [<CompilerMessage("This construct is for ML compatibility.", 62, IsHidden=true)>]
+                        member this.CompilerMesageMethod() = 100
+                        [<CompilerMessage("This construct is hidden", 1023, IsHidden=true)>]
+                        member this.HiddenMethod() = 10
+                        [<CompilerMessage("This construct is not hidden", 1023, IsHidden=false)>]
+                        member this.VisibleMethod() = 10
+                        [<CompilerMessage("This construct is not hidden", 1023)>]
+                        member this.VisibleMethod2() = 10
+                namespace NS2
+                module m2 =
+                type x = NS1.MyModule(*MarkerType*)
+                let b = (new NS1.MyModule.TestType())(*MarkerMethod*)
+                """,
+            marker = "(*MarkerMethod*)",
+            list = ["TestMethod";"VisibleMethod";"VisibleMethod2"])
+
+    [<Test>]
+    member this.``Method.DefInDiffNameSpace.WithAttributes.Negative``() =
+        this.VerifyDotCompListDoesNotContainAnyAtStartOfMarker(
+            fileContents = """
+                namespace NS1
+                module  MyModule =
+                    [<System.ObsoleteAttribute>]
+                    type ObsoleteType() = 
+                        member this.TestMethod() = 10        
+                    [<CompilerMessage("This construct is for ML compatibility.", 62, IsHidden=true)>]
+                    type CompilerMesageType() = 
+                        member this.TestMethod() = 10
+                    type TestType() = 
+                        member this.TestMethod() = 100
+                        [<System.ObsoleteAttribute>]
+                        member this.ObsoleteMethod() = 100
+                        [<CompilerMessage("This construct is for ML compatibility.", 62, IsHidden=true)>]
+                        member this.CompilerMesageMethod() = 100
+                        [<CompilerMessage("This construct is hidden", 1023, IsHidden=true)>]
+                        member this.HiddenMethod() = 10
+                        [<CompilerMessage("This construct is not hidden", 1023, IsHidden=false)>]
+                        member this.VisibleMethod() = 10
+                        [<CompilerMessage("This construct is not hidden", 1023)>]
+                        member this.VisibleMethod2() = 10
+                namespace NS2
+                module m2 =
+                type x = NS1.MyModule(*MarkerType*)
+                let b = (new NS1.MyModule.TestType())(*MarkerMethod*)""",
+            marker = "(*MarkerMethod*)",
+            list = ["ObsoleteMethod";"CompilerMesageMethod";"HiddenMethod"])
+
+    [<Test>]
+    member this.``ObjInstance.ExtensionMethods.WithDef.Positive``() =
+        this.VerifyDotCompListContainAllAtStartOfMarker(
+            fileContents = """
+                open System
+
+                type System.Random with
+                    member this.NextDice() = true
+                    member this.DiceValue = 6
+
+                let rnd = new System.Random()
+                rnd(*MWithReference*)""",
+            marker = "(*MWithReference*)",
+            list = ["NextDice";"DiceValue"]) 
+
+    [<Test>]
+    member this.``Keywords.If``() =
+        this.VerifyDotCompListIsEmptyAtStartOfMarker(
+            fileContents = """
+                if(*MarkerKeywordIf*) true then
+                    () """,
+            marker ="(*MarkerKeywordIf*)")
+
+    [<Test>]
+    member this.``Keywords.Let``() =
+        this.VerifyDotCompListIsEmptyAtStartOfMarker(
+            fileContents = """let(*MarkerKeywordLet*) a = 1""",
+            marker = "(*MarkerKeywordLet*)")
+
+    [<Test>]
+    member this.``Keywords.Match``() =
+        this.VerifyDotCompListIsEmptyAtStartOfMarker(
+            fileContents = """
+                match(*MarkerKeywordMatch*) a with
+                    | pattern -> exp""",
+            marker = "(*MarkerKeywordMatch*)")
+
+    [<Test>]
+    member this.``MacroDirectives.nowarn``() =
+        this.VerifyDotCompListIsEmptyAtStartOfMarker(
+            fileContents = """#nowarn(*MarkerPreProcessNowarn*)""",
+            marker = "(*MarkerPreProcessNowarn*)")
+
+    [<Test>]
+    member this.``MacroDirectives.light``() = 
+        this.VerifyDotCompListIsEmptyAtStartOfMarker(
+            fileContents = """#light(*MarkerPreProcessLight*)""",
+            marker = "(*MarkerPreProcessLight*)") 
+
+    [<Test>]
+    member this.``MacroDirectives.define``() =
+        this.VerifyDotCompListIsEmptyAtStartOfMarker(
+            fileContents = """#define(*MarkerPreProcessDefine*)""",
+            marker = "(*MarkerPreProcessDefine*)")
+
+    [<Test>]
+    member this.``MacroDirectives.PreProcessDefine``() =
+        this.VerifyDotCompListIsEmptyAtStartOfMarker(
+            fileContents = """#define Foo(*MarkerPreProcessDefineConst*)""",
+            marker = "(*MarkerPreProcessDefineConst*)")
+
+    [<Test>]
+    member this.``Identifier.InClass.WithoutDef``() =
+        this.VerifyDotCompListIsEmptyAtStartOfMarker(
+            fileContents = """
+                type Type2 =
+                    val mutable x(*MarkerValue*) : string""",
+            marker = "(*MarkerValue*)")
+
+    [<Test>]
+    member this.``Identifier.InDiscUnion.WithoutDef``() =
+        this.VerifyDotCompListIsEmptyAtStartOfMarker(
+            fileContents = """
+                type DUTag =
+                    |Tag(*MarkerDU*) of int""",
+            marker = "(*MarkerDU*)") 
+
+    [<Test>]
+    member this.``Identifier.InRecord.WithoutDef``() =
+        this.VerifyDotCompListIsEmptyAtStartOfMarker(
+            fileContents = """type Rec =  { X(*MarkerRec*) : int }""",
+            marker = "(*MarkerRec*)")
+            
+    [<Test>]
+    member this.``Identifier.AsNamespace``() =
+        this.VerifyDotCompListIsEmptyAtStartOfMarker(
+            fileContents = """namespace Namespace1(*MarkerNamespace*)""",
+            marker = "(*MarkerNamespace*)")
+
+    [<Test>]
+    member this.``Identifier.AsModule``() =
+        this.VerifyDotCompListIsEmptyAtStartOfMarker(
+            fileContents = """module Module1(*MarkerModule*)""",
+            marker = "(*MarkerModule*)")
+
+    [<Test>]
+    member this.``Identifier.WithouDef``() = 
+        this.VerifyDotCompListIsEmptyAtStartOfMarker(
+            fileContents = """ abcd(*MarkerUndefinedIdentifier*)  """,
+            marker = "(*MarkerUndefinedIdentifier*)") 
+
+    [<Test>]
+    member this.``Identifier.InMatch.UnderScore``() = 
+        this.VerifyDotCompListIsEmptyAtStartOfMarker(
+            fileContents = """
+                let x = 1
+                match x with 
+                    |1 -> 1*2
+                    |2 -> 2*2
+                    |_(*MarkerIdentifierIsUnderScore*) -> 0 """,
+            marker = "(*MarkerIdentifierIsUnderScore*)") 
+
+    [<Test>]
+    member this.MemberSelf() =
+        this.VerifyDotCompListIsEmptyAtStartOfMarker(
+            fileContents = """
+                type Foo() = 
+                    member this(*Mmemberself*)""",
+            marker = "(*Mmemberself*)")   
+
+    [<Test>]
+    member this.``Expression.InComment``() =
+        this.VerifyDotCompListIsEmptyAtStartOfMarker(
+            fileContents = """
+                //open System
+                //open IO = System(*Mcomment*)""",
+            marker = "(*Mcomment*)")
+
+    [<Test>]
+    member this.``Expression.InString``() =
+        this.VerifyDotCompListIsEmptyAtStartOfMarker(
+            fileContents = """let x = "System.Console(*Minstring*)" """,
+            marker = "(*Minstring*)")
+
+    // Regression test for 1067 -- Completion lists don't work after generic arguments  - for generic functions and for static members of generic types
+    [<Test>]
+    member this.``Regression1067.InstanceOfGeniricType``() =
+        this.VerifyDotCompListContainAllAtStartOfMarker(
+            fileContents = """
+                type GT<'a> =
+                    static member P = 12
+                    static member Q = 13
+
+                let _ = GT<int>(*Marker1*)
+                type gt_int = GT<int>
+                gt_int(*Marker2*)
+
+                type D =
+                 class
+                 end
+
+                let x = typeof<D>(*Marker3*)
+                let y = typeof<D>
+                y(*Marker4*)
+                """,
+            marker = "(*Marker2*)",
+            list = ["P"; "Q"]) 
+
+    [<Test>]
+    member this.``Regression1067.ClassUsingGeniricTypeAsAttribute``() =
+        this.VerifyDotCompListContainAllAtStartOfMarker(
+            fileContents = """
+                type GT<'a> =
+                    static member P = 12
+                    static member Q = 13
+
+                let _ = GT<int>(*Marker1*)
+                type gt_int = GT<int>
+                gt_int(*Marker2*)
+
+                type D =
+                 class
+                 end
+
+                let x = typeof<D>(*Marker3*)
+                let y = typeof<D>
+                y(*Marker4*)
+                """,
+            marker = "(*Marker4*)",
+            list = ["Assembly"; "FullName"; "GUID"])
+
+    [<Test>] 
+    member this.NoInfiniteLoopInProperties() =
+        let fileContents = """
+                open System.Windows.Forms
+
+                let tn = new TreeNode("")
+
+                tn.Nodes(*Marker1*)"""
+        let (solution, project, file) = this.CreateSingleFileProject(fileContents, references = ["System.Windows.Forms"])
+
+        let completions = DotCompletionAtStartOfMarker file "(*Marker1*)"
+        AssertCompListDoesNotContainAny(completions, ["Nodes"])
+    
+    // Regression for bug 3225 -- Invalid intellisense when inside of a quotation
+    [<Test>]
+    member this.``Regression3225.Identifier.InQuotation``() =
+        this.VerifyDotCompListContainAllAtStartOfMarker(
+            fileContents = """
+                let _ = <@ let x = "foo"
+                           x(*Marker*) @>""",
+           marker = "(*Marker*)",
+           list = ["Chars"; "Length"])
+
+    // Regression for bug 1911 -- No completion list of expr in match statement
+    [<Test>]
+    member this.``Regression1911.Expression.InMatchStatement``() =
+        this.VerifyDotCompListContainAllAtStartOfMarker(
+            fileContents = """
+                type Thingey = { A : bool; B : int }
+
+                let test = match (List.head [{A = true; B = 0}; {A = false; B = 1}])(*Marker*)""",
+            marker = "(*Marker*)",
+            list = ["A"; "B"])
+
+          
+    // Bug 3627 - Completion lists should be filtered in many contexts
+    // This blocks six testcases and is slated for Dev11, so these will be disabled for some time.
+    [<Test>]
+    [<Ignore("Bug 3627 - Completion lists should be filtered in many contexts")>] 
+    member this.AfterTypeParameter() =
+        let fileContents = """
+            type Type1 = Tag of string(*MarkerDUTypeParam*)
+
+            let f x:int -> string(*MarkerParamFunction*)
+
+            let Type2<'a(*MarkerGenericParam*)> = 1
+   
+            let type1 = typeof<int(*MarkerParamTypeof*)>
+            """
+        let (solution, project, file) = this.CreateSingleFileProject(fileContents)
+
+        //Completion list Not comes up after DUType parameter
+        let completions = DotCompletionAtStartOfMarker file "(*MarkerDUTypeParam*)"
+        AssertCompListIsEmpty(completions)
+
+        //Completion list Not comes up after function parameter
+        let completions = DotCompletionAtStartOfMarker file "(*MarkerParamFunction*)"
+        AssertCompListIsEmpty(completions)
+
+        //Completion list Not comes up after generic parameter
+        let completions = DotCompletionAtStartOfMarker file "(*MarkerGenericParam*)"
+        AssertCompListIsEmpty(completions)
+
+        //Completion list Not comes up after parameter in typeof
+        let completions = DotCompletionAtStartOfMarker file "(*MarkerParamTypeof*)"
+        AssertCompListIsEmpty(completions)
+
+    [<Test>]
+    member this.``Identifier.AsClassName.Uninitial``() =
+        this.VerifyDotCompListIsEmptyAtStartOfMarker(
+            fileContents = """
+                type f1(*MarkerType*) = 
+                    val field : int""",
+            marker = "(*MarkerType*)")
+
+    [<Test>]
+    member this.``Identifier.AsFunctionName.UnInitial``() =
+        this.VerifyDotCompListIsEmptyAtStartOfMarker(
+            fileContents = """let f2(*MarkerFunctionIndentifier*) x = x+1 """,
+            marker = "(*MarkerFunctionIndentifier*)")
+
+    [<Test>]
+    member this.``Identifier.AsParameter.UnInitial``() =
+        this.VerifyDotCompListIsEmptyAtStartOfMarker(
+            fileContents = """ let f3 x(*MarkerParam*) = x+1""",
+            marker = "(*MarkerParam*)")
+
+    [<Test>]
+    member this.``Identifier.AsFunctionName.UsingfunKeyword``() =
+        this.VerifyDotCompListIsEmptyAtStartOfMarker(
+            fileContents = """fun f4(*MarkerFunctionDeclaration*)  x -> x+1""",
+            marker = "(*MarkerFunctionDeclaration*)")
+
+    [<Test>]
+    member public this.``Identifier.EqualityConstraint.Bug65730``() =  
+        this.VerifyDotCompListContainAllAtStartOfMarker(
+            fileContents = """let g3<'a when 'a : equality> (x:'a) = x(*Marker*)""",
+            marker = "(*Marker*)",
+            list = ["Equals"; "GetHashCode"]) // equality constraint should make these show up
+ 
+    [<Test>]
+    [<Ignore("this no longer works, but I'm unclear why - now you get all the top-level completions")>]
+    member this.``Identifier.InFunctionMatch``() =
+        this.VerifyDotCompListIsEmptyAtStartOfMarker(
+            fileContents = """
+                let f5 = function
+                    | 1(*MarkerFunctionMatch*) -> printfn "1"
+                    | 2 -> printfn "2" """,
+            marker = "(*MarkerFunctionMatch*)")
+
+    [<Test>]
+    member this.``Identifier.This``() =
+        this.VerifyDotCompListIsEmptyAtStartOfMarker(
+            fileContents = """
+                type Type1 = 
+                    member this(*MarkerMemberThis*).Foo () = 3""",
+            marker = "(*MarkerMemberThis*)")
+
+    [<Test>]
+    member this.``Identifier.AsProperty``() =
+        this.VerifyDotCompListIsEmptyAtStartOfMarker(
+            fileContents = """
+                type Type2 =
+                    member this.Foo(*MarkerMemberThisProperty*) = 1""",
+            marker = "(*MarkerMemberThisProperty*)")
+
+    [<Test>]
+    member this.``ExpressionPropertyAssignment.Bug217051``() =  
+        this.VerifyDotCompListContainAllAtStartOfMarker(
+            fileContents = """
+                type Foo() =
+                    member val Prop = 0 with get, set
+ 
+                Foo()(*Marker*) <- 4 """,
+            marker = "(*Marker*)",
+            list = ["Prop"])
+
+    [<Test>]
+    member this.``ExpressionProperty.Bug234687``() =  
+        this.VerifyDotCompListContainAllAtStartOfMarker(
+            fileContents = """
+                open System.Reflection
+                let x = obj()
+                let a = x.GetType().Assembly(*Marker*)
+            """,
+            marker = "(*Marker*)",
+            list = ["CodeBase"]) // expect instance properties of Assembly, not static Assembly methods
+
+    [<Test>]
+    [<Ignore("Bug 3627 - Completion lists should be filtered in many contexts")>] 
+    member this.NotShowAttribute() =
+        let fileContents = """
+                open System
+
+                [<System.ObsoleteAttribute(*Mattribute1*)>]
+                type testclass() = 
+                    member x.Name() = "test"
+    
+                [<ObsoleteAttribute("stuff")(*Mattribute2*)>]
+                type testattribute() = 
+                    member x.Empty = 0
+                """
+        let (solution, project, file) = this.CreateSingleFileProject(fileContents)
+
+        //Completion List----where completion list does not come up
+        let completions = DotCompletionAtStartOfMarker file "(*Mattribute1*)"
+        AssertCompListIsEmpty(completions)
+        
+        //Completion List----type where completion list does not come up
+        let completions = DotCompletionAtStartOfMarker file "(*Mattribute2*)"
+        AssertCompListIsEmpty(completions)
+        
+    [<Test>]
+    [<Ignore("Bug 3627 - Completion lists should be filtered in many contexts")>] 
+    member this.NotShowPInvokeSignature() =
+        let fileContents = """
+                //open System
+                //open IO = System(*Mcomment*)
+
+                #if RELEASE
+                    System.Console(*Mdisablecode*)
+                #endif
+
+                let x = "System.Console(*Minstring*)"
+                """
+        let (solution, project, file) = this.CreateSingleFileProject(fileContents)
+
+
+        // description="Completion List----where completion list does not come up
+        let completions = DotCompletionAtStartOfMarker file "(*Mreturntype*)"
+        AssertCompListIsEmpty(completions)
+
+
+        // description="Completion List----type where completion list does not come up
+        let completions = DotCompletionAtStartOfMarker file "(*Mfunctionname*)"
+        AssertCompListIsEmpty(completions)
+
+
+        // description="Completion List----type where completion list does not come up
+        let completions = DotCompletionAtStartOfMarker file "(*Mparametertype*)"
+        AssertCompListIsEmpty(completions)
+
+
+        // description="Completion List----type where completion list does not come up
+        let completions = DotCompletionAtStartOfMarker file "(*Mparameter*)"
+        AssertCompListIsEmpty(completions)
+
+
+        // description="Completion List----type where completion list does not come up
+        let completions = DotCompletionAtStartOfMarker file "(*Mparameterlist*)"
+        AssertCompListIsEmpty(completions)
+
+    [<Test>]
+    member this.``Basic.Completion.UnfinishedLet``() = 
+        this.VerifyDotCompListContainAllAtStartOfMarker(
+            fileContents = """
+                let g(x) = x+1
+
+                let f() =
+                    let r = g(4)(*Marker*) """,
+            marker = "(*Marker*)",
+            list = ["CompareTo"])
+
+    [<Test>]
+    [<Ignore("I don't understand why this test doesn't work, but the product works")>]
+    member this.``ShortFormSeqExpr.Bug229610``() = 
+        this.VerifyDotCompListContainAllAtStartOfMarker(
+            fileContents = """
+                module test
+                    open System.Text.RegularExpressions
+ 
+                    let limit = 50
+                    let linkPat = "href=\s*\"[^\"h]*(http://[^&\"]*)\""
+                    let getLinks (txt:string) =  [ for m in Regex.Matches(txt,linkPat)  -> m.Groups.Item(1)(*Marker*) ]   """,
+            marker = "(*Marker*)",
+            list = ["Value"])
+
+    //Regression test for bug 69159 Fsharp: dot completion is mission for an array
+    [<Test>]
+    member this.``Array.InitialUsing..``() = 
+        this.VerifyDotCompListContainAllAtStartOfMarker(
+            fileContents = """let x1 = [| 0.0 .. 0.1 .. 10.0 |](*Marker*)""",
+            marker = "(*Marker*)",
+            list = ["Length";"Clone";"ToString"])
+
+    //Regression test for bug 65740 Fsharp: dot completion is mission after a '#' statement
+    [<Test>]
+    member this.``Identifier.In#Statement``() =
+        this.VerifyDotCompListContainAllAtStartOfMarker(
+            fileContents = """
+                # 29 "original-test-file.fs"
+                let argv = System.Environment.GetCommandLineArgs() 
+ 
+                let SetCulture() = 
+                  if argv(*Marker*)Length > 2 && argv.[1] = "--culture" then  
+                    let cultureString = argv.[2] 
+                """,
+            marker = "(*Marker*)",
+            list = ["Length";"Clone";"ToString"])
+
+    //This test is about CompletionList which should be moved to completionList, it's too special to refactor.
+    //Regression test for bug 72595 typing quickly yields wrong intellisense
+    [<Test>]
+    member this.``BadCompletionAfterQuicklyTyping``() =        
+        let code = [ "        " ]
+        let (_, _, file) = this.CreateSingleFileProject(code)
+
+        TakeCoffeeBreak(this.VS)
+        let gpatcc = GlobalParseAndTypeCheckCounter.StartNew(this.VS)
+
+        // In this case, we quickly type "." and then get dot-completions
+        // For "level <- Module" this shows completions from the "Module" (e.g. "Module.Other")
+        // This simulates the case when the user quickly types "dot" after the file has been TCed before.
+
+        ReplaceFileInMemoryWithoutCoffeeBreak file ([ "[1]." ])      
+        MoveCursorToEndOfMarker(file, ".")
+        TakeCoffeeBreak(this.VS)
+
+        let completions = AutoCompleteAtCursor file
+        AssertCompListContainsAll(completions, ["Length"])
+        AssertCompListDoesNotContainAny(completions, ["AbstractClassAttribute"]) 
+        gpatcc.AssertExactly(0,0)
+
+    [<Test>]
+    member this.``SelfParameter.InDoKeywordScope``() =
+        this.VerifyDotCompListContainAllAtStartOfMarker(
+            fileContents = """
+                type foo() as this =
+                    do
+                        this(*Marker*)""",
+            marker = "(*Marker*)",
+            list = ["ToString"])
+
+    [<Test>]
+    member this.``SelfParameter.InDoKeywordScope.Negative``() =
+        this.VerifyDotCompListDoesNotContainAnyAtStartOfMarker(
+            fileContents = """
+                type foo() as this =
+                    do
+                        this(*Marker*)""",
+            marker = "(*Marker*)",
+            list = ["Value";"Contents"])
+
+    [<Test>]
+    member this.``ReOpenNameSpace.StaticProperties``() =
+        this.VerifyDotCompListContainAllAtStartOfMarker(
+            fileContents = """
+                // Static properties & events
+                namespace A 
+                type TestType =
+                  static member Prop = 0
+                  static member Event = (new Event<int>()).Publish
+                namespace B
+                open A
+                open A
+                TestType(*Marker1*)""",
+            marker = "(*Marker1*)",
+            list = ["Prop";"Event"])
+
+    [<Test>]
+    member this.``ReOpenNameSpace.EnumTypes``() = 
+        this.VerifyDotCompListContainAllAtStartOfMarker(
+            fileContents = """
+                // F# declared enum types:
+                namespace A 
+                module Test = 
+                  type A = | Foo = 0
+
+                namespace B
+                open A
+                open A
+                Test.A(*Marker2*)
+                """,
+            marker = "(*Marker2*)",
+            list = ["Foo"])
+
+    [<Test>]
+    member this.``ReOpenNameSpace.SystemLibrary``() =
+        this.VerifyDotCompListContainAllAtStartOfMarker(
+            fileContents = """
+                module BasicTest
+                open System.IO
+                open System.IO
+
+                File(*Marker3*)
+                """,
+            marker = "(*Marker3*)",
+            list = ["Open"])
+
+    [<Test>]
+    member this.``ReOpenNameSpace.FsharpQuotation``() = 
+        this.VerifyDotCompListContainAllAtStartOfMarker(
+            fileContents = """
+                module BasicTest
+                open Microsoft.FSharp.Quotations
+                open Microsoft.FSharp.Quotations
+                Expr(*Marker4*)
+                """,
+            marker = "(*Marker4*)",
+            list = ["Value"])
+
+    [<Test>]
+    member this.``ReOpenNameSpace.MailboxProcessor``() =
+        this.VerifyDotCompListContainAllAtStartOfMarker(
+            fileContents = """
+                module BasicTest
+                open Microsoft.FSharp.Control
+                open Microsoft.FSharp.Control
+                let counter = 
+                    MailboxProcessor(*Marker6*)""",
+            marker = "(*Marker6*)",
+            list = ["Start"])
+
+    [<Test>]
+    member this.``ReopenNamespace.Module``() =
+        this.VerifyDotCompListContainAllAtStartOfMarker(
+            fileContents = """
+                namespace A 
+                module Test = 
+                  let foo n = n + 1
+                namespace B
+                open A
+                open A
+                Test(*Marker7*)""",
+            marker = "(*Marker7*)",
+            list = ["foo"])
+
+    [<Test>]
+    member this.``Expression.InLetScope``() =
+        this.VerifyDotCompListContainAllAtStartOfMarker(
+            fileContents = """
+                module BasicTest
+
+                let p4 = 
+                    let isPalindrome x = 
+                        let chars = (string_of_int x).ToCharArray()
+                        let len = chars(*Marker1*)
+                        chars 
+                        |> Array.mapi (fun i c -> (i(*Marker2*), c(*Marker3*))""",
+            marker = "(*Marker1*)",
+            list = ["IsFixedSize";"Initialize"])
+
+    [<Test>]
+    member this.``Expression.InFunScope.FirstParameter``() =
+        this.VerifyDotCompListContainAllAtStartOfMarker(
+            fileContents = """
+                module BasicTest
+                let p4 = 
+                    let isPalindrome x = 
+                        let chars = (string_of_int x).ToCharArray()
+                        let len = chars(*Marker1*)
+                        chars 
+                        |> Array.mapi (fun i c -> (i(*Marker2*), c(*Marker3*))""",
+            marker = "(*Marker2*)",
+            list = ["CompareTo"])
+
+    [<Test>]
+    member this.``Expression.InFunScope.SecParameter``() =
+        this.VerifyDotCompListContainAllAtStartOfMarker(
+            fileContents = """
+                module BasicTest
+
+                let p4 = 
+                    let isPalindrome x = 
+                        let chars = (string_of_int x).ToCharArray()
+                        let len = chars(*Marker1*)
+                        chars 
+                        |> Array.mapi (fun i c -> (i(*Marker2*), c(*Marker3*))""",
+            marker = "(*Marker3*)",
+            list = ["GetType";"ToString"])
+
+    [<Test>]
+    member this.``Expression.InMatchWhenClause``() =
+        this.VerifyDotCompListContainAllAtStartOfMarker(
+            fileContents = """
+                module BasicTest
+                type DU = X of int
+
+                let timefilter pkt =
+                    match pkt with
+                    | X(hdr) when hdr(*MarkerMatch*) -> ()
+                    | _ -> ()
+                """,
+            marker = "(*MarkerMatch*)",
+            list = ["CompareTo";"ToString"])
+
+    //Regression test for bug 3223 in PS: No intellisense at point
+    [<Test>]
+    member this.``Identifier.InActivePattern.Positive``() =
+        this.VerifyDotCompListContainAllAtStartOfMarker(
+            fileContents = """
+                module BasicTest
+                // regression test for bug 3223  No intellisense at point
+
+                open Microsoft.FSharp.Quotations.Patterns
+                open Microsoft.FSharp.Quotations.DerivedPatterns
+
+                let test1 = <@ 1 + 1 @>
+                let _ =
+                    match test1 with
+                    | Call(None, methInfo, args) ->
+                        if methInfo(*Marker*)
+                """,
+            marker = "(*Marker*)",
+            list = ["Attributes";"CallingConvention";"ContainsGenericParameters"])
+
+    [<Test>]
+    member this.``Identifier.InActivePattern.Negative``() =
+        this.VerifyDotCompListDoesNotContainAnyAtStartOfMarker(
+            fileContents = """
+                module BasicTest
+                // regression test for bug 3223  No intellisense at point
+
+                open Microsoft.FSharp.Quotations.Patterns
+                open Microsoft.FSharp.Quotations.DerivedPatterns
+
+                let test1 = <@ 1 + 1 @>
+                let _ =
+                    match test1 with
+                    | Call(None, methInfo, args) ->
+                        if methInfo(*Marker*)
+                """,
+            marker = "(*Marker*)",
+            list = ["Head";"ToInt"])
+
+   //Regression test of bug 2296:No completion lists on the direct results of a method call
+    [<Test>] 
+    member this.``Regression2296.DirectResultsOfMethodCall``() =
+        this.VerifyDotCompListContainAllAtStartOfMarker(
+            fileContents = """
+                module BasicTest
+                // regression test of bug 2296: No completion lists on the direct results of a method call
+
+                // This is a function that has a custom attribute on the return type.
+                let foo(a) : [<Core.OCamlCompatibilityAttribute("Attribute on return type!")>] int
+                   = a + 5
+
+                // The rest of the code is a mere verification that the compiler thru reflection
+                let executingAssembly = System.Reflection.Assembly.GetExecutingAssembly()
+                let programType = executingAssembly.GetType("Program")
+                let message = programType.GetMethod("foo")(*Marker1*)
+                """,
+            marker = "(*Marker1*)",
+            list = ["Attributes";"CallingConvention";"IsFamily"])
+
+    [<Test>]
+    member this.``Regression2296.DirectResultsOfMethodCall.Negative``() = 
+        this.VerifyDotCompListDoesNotContainAnyAtStartOfMarker(
+            fileContents = """
+                module BasicTest
+                // regression test of bug 2296: No completion lists on the direct results of a method call
+
+                // This is a function that has a custom attribute on the return type.
+                let foo(a) : [<Core.OCamlCompatibilityAttribute("Attribute on return type!")>] int
+                   = a + 5
+
+                // The rest of the code is a mere verification that the compiler thru reflection
+                let executingAssembly = System.Reflection.Assembly.GetExecutingAssembly()
+                let programType = executingAssembly.GetType("Program")
+                let message = programType.GetMethod("foo")(*Marker1*)
+                """,
+            marker = "(*Marker1*)",
+            list = ["value__"])                     
+
+    [<Test>]
+    member this.``Regression2296.Identifier.String.Reflection01``() =
+        this.VerifyDotCompListContainAllAtStartOfMarker(
+            fileContents = """
+                module BasicTest
+                // regression test of bug 2296: No completion lists on the direct results of a method call
+
+                // This is a function that has a custom attribute on the return type.
+                let foo(a) : [<Core.OCamlCompatibilityAttribute("Attribute on return type!")>] int
+                    = a + 5
+
+                // The rest of the code is a mere verification that the compiler thru reflection
+                let executingAssembly = System.Reflection.Assembly.GetExecutingAssembly()
+
+                let programType = executingAssembly.GetType("Program")
+
+                let message = programType.GetMethod("foo")(*Marker1*)
+
+                let x = ""
+                let _ = x.Contains("a")(*Marker2*)""",
+            marker = "(*Marker2*)",
+            list = ["CompareTo";"GetType";"ToString"])  
+
+    [<Test>]
+    member this.``Regression2296.Identifier.String.Reflection01.Negative``() = 
+        this.VerifyDotCompListDoesNotContainAnyAtStartOfMarker(
+            fileContents = """
+                module BasicTest
+                // regression test of bug 2296: No completion lists on the direct results of a method call
+
+                // This is a function that has a custom attribute on the return type.
+                let foo(a) : [<Core.OCamlCompatibilityAttribute("Attribute on return type!")>] int
+                   = a + 5
+
+                // The rest of the code is a mere verification that the compiler thru reflection
+                let executingAssembly = System.Reflection.Assembly.GetExecutingAssembly()
+
+                let programType = executingAssembly.GetType("Program")
+
+                let message = programType.GetMethod("foo")(*Marker1*)
+
+                let x = ""
+                let _ = x.Contains("a")(*Marker2*)""",
+            marker = "(*Marker2*)",
+            list = ["value__"])  
+
+    [<Test>]
+    member this.``Regression2296.Identifier.String.Reflection02``() = 
+        this.VerifyDotCompListContainAllAtStartOfMarker(
+            fileContents = """
+                module BasicTest
+                // regression test of bug 2296: No completion lists on the direct results of a method call
+
+                // This is a function that has a custom attribute on the return type.
+                let foo(a) : [<Core.OCamlCompatibilityAttribute("Attribute on return type!")>] int
+                   = a + 5
+
+                // The rest of the code is a mere verification that the compiler thru reflection
+                let executingAssembly = System.Reflection.Assembly.GetExecutingAssembly()
+
+                let programType = executingAssembly.GetType("Program")
+
+                let message = programType.GetMethod("foo")(*Marker1*)
+
+                let x = ""
+                let _ = x.Contains("a")(*Marker2*)
+                let _ = x.CompareTo("a")(*Marker3*)""",
+            marker = "(*Marker3*)",
+            list = ["CompareTo";"GetType";"ToString"]) 
+
+    [<Test>]
+    member this.``Regression2296.Identifier.String.Reflection02.Negative``() = 
+        this.VerifyDotCompListDoesNotContainAnyAtStartOfMarker(
+            fileContents = """
+                module BasicTest
+                // regression test of bug 2296: No completion lists on the direct results of a method call
+
+                // This is a function that has a custom attribute on the return type.
+                let foo(a) : [<Core.OCamlCompatibilityAttribute("Attribute on return type!")>] int
+                   = a + 5
+
+                // The rest of the code is a mere verification that the compiler thru reflection
+                let executingAssembly = System.Reflection.Assembly.GetExecutingAssembly()
+                let programType = executingAssembly.GetType("Program")
+                let message = programType.GetMethod("foo")(*Marker1*)
+                let x = ""
+                let _ = x.Contains("a")(*Marker2*)
+                let _ = x.CompareTo("a")(*Marker3*)""",
+            marker = "(*Marker3*)",
+            list = ["value__"])  
+
+    [<Test>]
+    member this.``Regression2296.System.StaticMethod.Reflection``() = 
+        this.VerifyDotCompListContainAllAtStartOfMarker(
+            fileContents = """
+                module BasicTest
+                // regression test of bug 2296: No completion lists on the direct results of a method call
+
+                // This is a function that has a custom attribute on the return type.
+                let foo(a) : [<Core.OCamlCompatibilityAttribute("Attribute on return type!")>] int
+                   = a + 5
+
+                // The rest of the code is a mere verification that the compiler thru reflection
+                let executingAssembly = System.Reflection.Assembly.GetExecutingAssembly()
+                let programType = executingAssembly.GetType("Program")
+                let message = programType.GetMethod("foo")(*Marker1*)
+                let x = ""
+                let _ = x.Contains("a")(*Marker2*)
+                let _ = x.CompareTo("a")(*Marker3*)
+
+                open System.IO
+
+                let GetFileSize filePath = File.GetAttributes(filePath)(*Marker4*)""",
+            marker = "(*Marker4*)",
+            list = ["CompareTo";"GetType";"ToString"]) 
+
+    [<Test>]
+    member this.``Regression2296.System.StaticMethod.Reflection.Negative``() =
+        this.VerifyDotCompListDoesNotContainAnyAtStartOfMarker(
+            fileContents = """
+                module BasicTest
+                // regression test of bug 2296: No completion lists on the direct results of a method call
+
+                // This is a function that has a custom attribute on the return type.
+                let foo(a) : [<Core.OCamlCompatibilityAttribute("Attribute on return type!")>] int
+                   = a + 5
+
+                // The rest of the code is a mere verification that the compiler thru reflection
+                let executingAssembly = System.Reflection.Assembly.GetExecutingAssembly()
+                let programType = executingAssembly.GetType("Program")
+                let message = programType.GetMethod("foo")(*Marker1*)
+                let x = ""
+                let _ = x.Contains("a")(*Marker2*)
+                let _ = x.CompareTo("a")(*Marker3*)
+
+                open System.IO
+
+                let GetFileSize filePath = File.GetAttributes(filePath)(*Marker4*)""",
+            marker = "(*Marker4*)",
+            list = ["value__"])    
+
+    [<Test>]
+    member this.``Seq.NearTheEndOfFile``() =
+        this.VerifyDotCompListContainAllAtStartOfMarker(
+            fileContents = """
+                module BasicTest
+                open Microsoft.FSharp.Math
+
+                let trianglenumbers = Seq.init_infinite (fun i -> let i = BigInt(i) in i * (i+1I) / 2I)
+
+                (trianglenumbers |> Seq(*MarkerNearTheEnd*))""",
+            marker = "(*MarkerNearTheEnd*)",
+            list = ["cache";"find"])
+
+    //Regression test of bug 3879: intellisense glitch for computation expression
+    [<Test>]
+    [<Ignore("This is still fail")>]
+    member this.``ComputationExpression.WithClosingBrace``() = 
+        this.VerifyDotCompListContainAllAtStartOfMarker(
+            fileContents = """
+                module BasicTest
+                // regression test for bug 3879: intellisense glitch for computation expression
+                // intellisense does not work in computation expression without the closing brace
+                type System.Net.WebRequest with
+
+                    member x.AsyncGetResponse() = Async.BuildPrimitive(x.BeginGetResponse, x.EndGetResponse)
+                    member x.GetResponseAsync() = x.AsyncGetResponse()
+
+                let http(url:string) = 
+                     async {let req = System.Net.WebRequest.Create("http://www.yahoo.com")
+                            let! rsp = req(*Marker*)} """,
+            marker = "(*Marker*)",
+            list = ["AsyncGetResponse";"GetResponseAsync";"ToString"])
+
+    [<Test>]
+    [<Ignore("This is still fail")>]
+    member this.``ComputationExpression.WithoutClosingBrace``() = 
+        this.VerifyDotCompListContainAllAtStartOfMarker(
+            fileContents = """
+                module BasicTest
+                // regression test for bug 3879: intellisense glitch for computation expression
+                // intellisense does not work in computation expression without the closing brace
+                type System.Net.WebRequest with
+
+                    member x.AsyncGetResponse() = Async.BuildPrimitive(x.BeginGetResponse, x.EndGetResponse)
+                    member x.GetResponseAsync() = x.AsyncGetResponse()
+
+                let http(url:string) = 
+                    async { let req = System.Net.WebRequest.Create("http://www.yahoo.com")
+                            let! rsp = req(*Marker*) """,           
+            marker = "(*Marker*)",
+            list = ["AsyncGetResponse";"GetResponseAsync";"ToString"])  
+
+    //Regression Test of 4405:intelisense has wrong type for identifier, using most recently bound of same name rather than the one in scope?
+    [<Test>]
+    member this.``Regression4405.Identifier.ReBinded``() =
+        this.VerifyDotCompListContainAllAtStartOfMarker(
+            fileContents = """
+                let f x = 
+                    let varA = "string"
+                    let varA = if x then varA(*MarkerRebound*) else 2
+                    varA""",
+            marker = "(*MarkerRebound*)",
+            list = ["Chars";"StartsWith"])
+
+    //Regression test for FSharp1.0:4702
+    [<Test>]
+    member this.``Regression4702.SystemWord``() =
+        this.VerifyDotCompListContainAllAtStartOfMarker(
+            fileContents = "System(*Marker*)",
+            marker = "(*Marker*)",
+            list = ["Console";"Byte";"ArgumentException"])
+
+    [<Test>]
+    member this.``TypeAbbreviation.Positive``() =
+        this.VerifyDotCompListContainAllAtStartOfMarker(
+            fileContents = """
+                module BasicTest
+
+                Microsoft.FSharp.Core(*Marker1*)""",
+            marker = "(*Marker1*)",
+            list = ["int16";"int32";"int64"])
+
+    [<Test>]
+    member this.``TypeAbbreviation.Negative``() =
+        this.VerifyDotCompListDoesNotContainAnyAtStartOfMarker(
+            fileContents = """
+                module BasicTest
+
+                Microsoft.FSharp.Core(*Marker1*)""",
+            marker = "(*Marker1*)",
+            list = ["Int16";"Int32";"Int64"])    
+
+    //Regression test of bug 3754:tupe forwarder bug? intellisense bug?
+    [<Test>]
+    member this.``Regression3754.TypeOfListForward.Positive``() =
+        this.VerifyDotCompListContainAllAtStartOfMarker(
+            fileContents = """
+                module BasicTest
+                // regression test for bug 3754
+                // tupe forwarder bug? intellisense bug?
+
+                open System.IO
+                open System.Xml
+                open System.Xml.Linq 
+                let xmlStr = @"<?xml version='1.0' encoding='UTF-8'?><doc>    <blah>Blah</blah>    <a href='urn:foo' />    <yadda>        <blah>Blah</blah>        <a href='urn:bar' />    </yadda></doc>"
+                let xns = XNamespace.op_Implicit ""
+                let a = xns + "a"
+                let reader = new StringReader(xmlStr)
+                let xdoc = XDocument.Load(reader)
+                let aElements = [for x in xdoc.Root.Elements() do
+                                    if x.Name = a then
+                                        yield x]
+                let href = xns + "href"
+                aElements |> List(*Marker*)""",
+            marker = "(*Marker*)",
+            list = ["append";"choose";"isEmpty"])
+
+    [<Test>]
+    member this.``Regression3754.TypeOfListForward.Negative``() =
+        this.VerifyDotCompListDoesNotContainAnyAtStartOfMarker(
+            fileContents = """
+                module BasicTest
+                // regression test for bug 3754
+                // tupe forwarder bug? intellisense bug?
+
+                open System.IO
+                open System.Xml
+                open System.Xml.Linq 
+                let xmlStr = @"<?xml version='1.0' encoding='UTF-8'?><doc>    <blah>Blah</blah>    <a href='urn:foo' />    <yadda>        <blah>Blah</blah>        <a href='urn:bar' />    </yadda></doc>"
+                let xns = XNamespace.op_Implicit ""
+                let a = xns + "a"
+                let reader = new StringReader(xmlStr)
+                let xdoc = XDocument.Load(reader)
+                let aElements = [for x in xdoc.Root.Elements() do
+                                    if x.Name = a then
+                                        yield x]
+                let href = xns + "href"
+                aElements |> List(*Marker*)""",
+            marker = "Marker",
+            list = ["<Note>"])
+
+    [<Test>]
+    member this.``NonApplicableExtensionMembersDoNotAppear.Bug40379``() =
+        let code =
+                                    [ "open System.Xml.Linq"
+                                      "type MyType() ="
+                                      "   static member Foo(actual:XElement) =  actual.Name "
+                                      "   member public this.Bar1() ="
+                                      "      let actual1 : int[] = failwith \"\""
+                                      "      actual1.(*Marker*)" 
+                                      "   member public this.Bar2() ="
+                                      "      let actual2 : XNode[] = failwith \"\""
+                                      "      actual2.(*Marker*)" 
+                                      "   member public this.Bar3() ="
+                                      "      let actual3 : XElement[] = failwith \"\""
+                                      "      actual3.(*Marker*)" 
+                                      ]
+        let (_, _, file) = this.CreateSingleFileProject(code, references = ["System.Xml"; "System.Xml.Linq"])
+        MoveCursorToEndOfMarker(file, "actual1.")
+        let completions = AutoCompleteAtCursor file
+        AssertCompListDoesNotContainAny(completions, [ "Ancestors"; "AncestorsAndSelf"])
+        MoveCursorToEndOfMarker(file, "actual2.")
+        let completions = AutoCompleteAtCursor file
+        AssertCompListContains(completions, "Ancestors")
+        AssertCompListDoesNotContain(completions, "AncestorsAndSelf")
+        MoveCursorToEndOfMarker(file, "actual3.")
+        let completions = AutoCompleteAtCursor file
+        AssertCompListContainsAll(completions, ["Ancestors"; "AncestorsAndSelf"])
+
+    [<Test>]
+    member this.``Visibility.InternalMethods.DefInSameAssambly``() =
+        this.VerifyDotCompListContainAllAtStartOfMarker(
+            fileContents = """
+                module CodeAccessibility
+                open System
+                module Module1 =
+
+                type Type1()=
+                    [<DefaultValue>]
+                    val mutable internal fieldInternal:int
+       
+                    member internal x.MethodInternal (x:int) = x+2
+        
+                let type1 = new Type1()
+
+                type1(*MarkerSameAssemb*)""",
+            marker = "(*MarkerSameAssemb*)",
+            list = ["fieldInternal";"MethodInternal"])
+
+    [<Test>]
+    member this.``QueryExpression.DotCompletionSmokeTest1``() = 
+        this.VerifyDotCompListContainAllAtStartOfMarker(
+            fileContents = """
+                module Basic
+                let x2 = query { for x in ["1";"2";"3"] do 
+                                 select x(*Marker*)""",
+            marker = "(*Marker*)",
+            list = ["Chars";"Length"],
+            addtlRefAssy=standard40AssemblyRefs)
+
+    member this.``QueryExpression.DotCompletionSmokeTest2``() = 
+           this.VerifyDotCompListContainAllAtStartOfMarker(
+              fileContents = """
+                module BasicTest
+                let x = query { for x in ["1";"2";"3"] do select x(*Marker*)""" ,
+              marker = "(*Marker*)",
+              list = ["Chars"; "Length"],
+              addtlRefAssy=standard40AssemblyRefs )
+
+    [<Test>]
+    member this.``QueryExpression.DotCompletionSmokeTest0``() = 
+           this.VerifyDotCompListContainAllAtStartOfMarker(
+              fileContents = """
+                module BasicTest
+                let x = seq { for x in ["1";"2";"3"] do yield x(*Marker*) }""" ,
+              marker = "(*Marker*)",
+              list = ["Chars";"Length"],
+              addtlRefAssy=standard40AssemblyRefs )
+
+
+    [<Test>]
+    member this.``QueryExpression.DotCompletionSmokeTest3``() = 
+           this.VerifyDotCompListContainAllAtStartOfMarker(
+              fileContents = """
+                module BasicTest
+                let x = query { for x in ["1";"2";"3"] do select x(*Marker*) }""" ,
+              marker = "(*Marker*)",
+              list = ["Chars";"Length"],
+              addtlRefAssy=standard40AssemblyRefs )
+
+
+    [<Test>]
+    member this.``QueryExpression.DotCompletionSystematic1``() = 
+      for customOperation in ["select";"sortBy";"where"] do
+        let fileContentsList = 
+            ["""
+                module Simple
+                let x2 = query { for x in ["1";"2";"3"] do 
+                                 """+customOperation+""" x(*Marker*)"""
+             """
+                module Simple
+                let x2 = query { for x in ["1";"2";"3"] do 
+                                 """+customOperation+""" (x(*Marker*)""" 
+             """
+                module Simple
+                let x2 = query { for x in ["1";"2";"3"] do 
+                                 """+customOperation+""" (x(*Marker*) }""" 
+             """
+                module Simple
+                let x2 = query { for x in ["1";"2";"3"] do 
+                                 """+customOperation+""" (x(*Marker*)
+                                 select x""" 
+             """
+                module Simple
+                let x2 = query { for x in ["1";"2";"3"] do 
+                                 """+customOperation+""" x(*Marker*)
+                                 select x }""" 
+             """
+                module Simple
+                let x2 = query { for x in ["1";"2";"3"] do 
+                                 """+customOperation+""" (x(*Marker*))""" 
+             """
+                module Simple
+                let x2 = query { for x in ["1";"2";"3"] do 
+                                 """+customOperation+""" (x.Length + x(*Marker*)"""
+             """
+                module Simple
+                let x2 = query { for x in [1;2;3] do 
+                                 for y in ["1";"2";"3"] do 
+                                 """+customOperation+""" (x + y(*Marker*)""" 
+             """
+                module Simple
+                let x2 = query { for x in [1;2;3] do 
+                                 for y in ["1";"2";"3"] do 
+                                 """+customOperation+""" (x + y(*Marker*))""" 
+             """
+                module Simple
+                let x2 = query { for x in [1;2;3] do 
+                                 for y in ["1";"2";"3"] do 
+                                 where (x > y.Length)
+                                 """+customOperation+""" (x + y(*Marker*)""" ] 
+        for fileContents in fileContentsList do 
+            printfn "customOperation = %s, fileContents = <<<%s>>>" customOperation fileContents
+            this.VerifyDotCompListContainAllAtStartOfMarker(
+                fileContents = fileContents,
+                marker = "(*Marker*)",
+                list = ["Chars";"Length"],
+                addtlRefAssy=standard40AssemblyRefs)
+
+    [<Test>] 
+    member public this.``QueryExpression.InsideJoin.Bug204147``() =        
+           this.VerifyDotCompListContainAllAtStartOfMarker(
+              fileContents = """
+                    module Simple
+                    type T() =
+                         member x.GetCollection() = [1;2;3;4]
+                    let q =
+                        query {
+                           for e in [1..10] do
+                           join b in T()(*Marker*)
+                           select b
+                        }""",
+              marker = "(*Marker*)",
+              list = ["GetCollection"],
+              addtlRefAssy=queryAssemblyRefs )
+
+(*------------------------------------------IDE Query automation start -------------------------------------------------*)
+
+    member private this.AssertDotCompletionListInQuery(fileContents: string, marker : string, list : string list) =
+        let datacode = """
+        namespace DataSource
+        open System
+        open System.Xml.Linq
+        type Product() =
+            let mutable id = 0
+            let mutable name = ""
+            let mutable category = ""
+            let mutable price = 0M
+            let mutable unitsInStock = 0
+            member x.ProductID with get() = id and set(v) = id <- v
+            member x.ProductName with get() = name and set(v) = name <- v
+            member x.Category with get() = category and set(v) = category <- v
+            member x.UnitPrice with get() = price and set(v) = price <- v
+            member x.UnitsInStock with get() = unitsInStock and set(v) = unitsInStock <- v
+
+        module Products =
+            let getProductList() =
+                [
+                Product(ProductID = 1, ProductName = "Chai", Category = "Beverages", UnitPrice = 18.0000M, UnitsInStock = 39 );
+                Product(ProductID = 2, ProductName = "Chang", Category = "Beverages", UnitPrice = 19.0000M, UnitsInStock = 17 ); 
+                Product(ProductID = 3, ProductName = "Aniseed Syrup", Category = "Condiments", UnitPrice = 10.0000M, UnitsInStock = 13 );
+                ] 
+        """
+        use _guard = this.UsingNewVS()
+        let solution = this.CreateSolution()
+        let project = CreateProject(solution,"testproject")
+        this.AddAssemblyReference(project, "System.Xml.Linq")
+        let file1 = AddFileFromTextBlob(project,"File1.fs",datacode)
+        //build
+        let file2 = AddFileFromTextBlob(project,"File2.fs",fileContents)
+        let file1 = OpenFile(project,"File1.fs")
+        let file2 = OpenFile(project,"File2.fs")
+
+        TakeCoffeeBreak(this.VS)
+        let completions = DotCompletionAtStartOfMarker file2 marker
+        AssertCompListContainsAll(completions, list) 
+
+    [<Test>]
+    [<Category("Query")>]
+    [<Ignore("196230")>]
+    // Intellisense still appears on arguments when the operator is used in error 
+    member public this.``Query.HasErrors.Bug196230``() =
+        this.AssertDotCompletionListInQuery(
+              fileContents = """
+                open DataSource
+                // defined in another file; see AssertDotCompletionListInQuery
+                let products = Products.getProductList()
+                let sortedProducts =
+                    query {
+                        for p in products do
+                        let x = p.ProductID + "a"
+                        sortBy p(*Marker*)
+                        select p
+                    }""" ,
+              marker = "(*Marker*)",
+              list = ["ProductID";"ProductName"] )
+
+    [<Test>]
+    [<Category("Query")>]
+    // Intellisense still appears on arguments when the operator is used in error 
+    member public this.``Query.HasErrors2``() =
+        this.AssertDotCompletionListInQuery(
+              fileContents = """
+                open DataSource
+                let products = Products.getProductList()
+                let sortedProducts =
+                    query {
+                        for p in products do
+                        orderBy (p(*Marker*))
+                    }""" ,
+              marker = "(*Marker*)",
+              list = ["ProductID";"ProductName"] )
+
+    [<Test>]
+    [<Category("Query")>]
+    // Shadowed variables have correct Intellisense
+    member public this.``Query.ShadowedVariables``() =
+        this.AssertDotCompletionListInQuery(
+              fileContents = """
+                open DataSource
+                let products = Products.getProductList()
+                let p = 12
+                let sortedProducts =
+                    query {
+                        for p in products do
+                        select p(*Marker*)
+                    }""" ,
+              marker = "(*Marker*)",
+              list = ["Category";"ProductName"] )
+
+    [<Test>]
+    [<Category("Query")>]
+    // Intellisense works correctly in a nested query
+    member public this.``Query.InNestedQuery``() =
+        let fileContents = """
+        let tuples = [ (1, 8, 9); (56, 45, 3)] 
+        let numbers = [ 1;2; 8; 9; 15; 23; 3; 42; 4;0; 55;]
+
+        let foo = 
+            query {
+                for n in numbers do
+                let maxNumber = query {for x in tuples do maxBy x(*Marker1*)}
+                select (n, query {for y in numbers do minBy y(*Marker2*)}) }
+        """
+        this.VerifyDotCompListContainAllAtStartOfMarker(fileContents, "(*Marker1*)", 
+            ["Equals";"GetType"], queryAssemblyRefs )
+        this.VerifyDotCompListContainAllAtStartOfMarker(fileContents, "(*Marker2*)", 
+            ["Equals";"CompareTo"], queryAssemblyRefs )
+
+    [<Test>]
+    [<Category("Query")>]
+    // Intellisense works correctly in a nested expression within a lamda
+    member public this.``Query.NestedExpressionWithinLamda``() =
+        let fileContents = """
+        let numbers = [ 1;2; 8; 9; 15; 23; 3; 42; 4;0; 55;]
+        let f (x : string) = ()
+        let foo = 
+            query {
+                for n in numbers do
+                let x = 42 |> ignore; numbers |> List.iter( fun n -> f ("1" + "1")(*Marker*))
+                skipWhile (n < 30)
+                 }
+        """
+        this.VerifyDotCompListContainAllAtStartOfMarker(fileContents, "(*Marker*)", 
+            ["Chars";"Length"], queryAssemblyRefs )
+
+// Allow the CompletionListTests run under different context
+namespace UnitTests.Tests.LanguageService.CompletionList
+open UnitTests.Tests.LanguageService
+open UnitTests.TestLib.LanguageService
+open UnitTests.TestLib.ProjectSystem
+open NUnit.Framework
+open Salsa.Salsa
+
+// context msbuild
+[<TestFixture>]
+[<Category("LanguageService.MSBuild")>] 
+type ``AutoCompletionMSBuild`` = 
+   inherit AutoCompletionListTests
+   new() = { inherit AutoCompletionListTests(VsOpts = fst (Models.MSBuild())); }
+
+// Context project system
+[<TestFixture>] 
+[<Category("LanguageService.ProjectSystem")>]
+type ``AutoCompletionProjectSystem`` = 
+    inherit AutoCompletionListTests
+    new() = { inherit AutoCompletionListTests(VsOpts = LanguageServiceExtension.ProjectSystem); } 
+
+// context msbuild
+[<TestFixture>] 
+[<Category("LanguageService.MSBuild")>]
+type ``DotCompletionMSBuild`` = 
+   inherit DotCompletionListTests
+   new() = { inherit DotCompletionListTests(VsOpts = fst (Models.MSBuild())); }
+
+// Context project system
+[<TestFixture>] 
+[<Category("LanguageService.ProjectSystem")>]
+type ``DotCompletionProjectSystem`` = 
+    inherit DotCompletionListTests
+    new() = { inherit DotCompletionListTests(VsOpts = LanguageServiceExtension.ProjectSystem); } 
+
+
+               
diff --git a/vsintegration/src/unittests/Tests.LanguageService.ErrorList.fs b/vsintegration/src/unittests/Tests.LanguageService.ErrorList.fs
new file mode 100644
index 0000000..48df42f
--- /dev/null
+++ b/vsintegration/src/unittests/Tests.LanguageService.ErrorList.fs
@@ -0,0 +1,948 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+namespace UnitTests.Tests.LanguageService
+
+open System
+open System.IO
+open NUnit.Framework
+open Salsa.Salsa
+open Salsa.VsOpsUtils
+open UnitTests.TestLib.Salsa
+open UnitTests.TestLib.Utils
+open UnitTests.TestLib.LanguageService
+
+type ErrorListTests() as this = 
+    inherit LanguageServiceBaseTests()
+
+    let VerifyErrorListContainedExpectedStr(expectedStr:string,project : OpenProject) = 
+        let convertNewlines (s:string) = s.Replace("\r\n", " ").Replace("\n", " ")
+        let errorList = GetErrors(project)
+        let GetErrorMessages(errorList : Error list) =
+            [ for i = 0 to errorList.Length - 1 do
+                yield errorList.[i].Message]
+        let msgs = GetErrorMessages errorList
+        if msgs |> Seq.exists (fun errorMessage -> convertNewlines(errorMessage).Contains(convertNewlines expectedStr)) then
+            ()
+        else
+            Assert.Fail(sprintf "Expected errors to contain '%s' but it was not there; errors were %A" expectedStr msgs)
+
+    let GetWarnings(project : OpenProject) =
+        let errorList = GetErrors(project)
+        [for error in errorList do
+            if (error.Severity = Microsoft.VisualStudio.FSharp.LanguageService.Severity.Warning) then
+            yield error]
+    
+    let CheckErrorList (content : string) f : unit = 
+        let (_, project, file) = this.CreateSingleFileProject(content)
+        Build(project) |> ignore
+
+        TakeCoffeeBreak(this.VS)
+        let errors = GetErrors project
+        printfn "==="
+        for err in errors do
+            printfn "%s" err.Message
+        f errors
+
+    let assertContains (errors : list<Error>) text = 
+        let ok = errors |> List.exists (fun err -> err.Message = text)
+        Assert.IsTrue(ok, sprintf "Error list should contain '%s' message" text)
+
+
+    //verify the error list Count
+    member private this.VerifyErrorListCountAtOpenProject(fileContents : string, num : int) =
+        let (solution, project, file) = this.CreateSingleFileProject(fileContents)
+        let errorList = GetErrors(project)
+        for error in errorList do
+            printfn "%A" error.Severity
+            printf "%s\n" (error.ToString()) 
+        if (num = errorList.Length) then 
+                ()
+            else
+                failwithf "The error list number is not the expected %d" num
+
+    //Verify the warning list Count
+    member private this.VerifyWarningListCountAtOpenProject(fileContents : string, expectedNum : int, ?addtlRefAssy : list<string>) = 
+        let (solution, project, file) = this.CreateSingleFileProject(fileContents, ?references = addtlRefAssy)
+        
+        TakeCoffeeBreak(this.VS) // Wait for the background compiler to catch up.
+        let warnList = GetWarnings(project)
+        Assert.AreEqual(expectedNum,warnList.Length)
+
+    //verify no the error list 
+    member private this.VerifyNoErrorListAtOpenProject(fileContents : string, ?addtlRefAssy : list<string>) = 
+        let (solution, project, file) = this.CreateSingleFileProject(fileContents, ?references = addtlRefAssy)
+        
+        TakeCoffeeBreak(this.VS) // Wait for the background compiler to catch up.
+        let errorList = GetErrors(project)      
+        for error in errorList do
+            printfn "%A" error.Severity
+            printf "%s\n" (error.ToString()) 
+        Assert.IsTrue(errorList.IsEmpty)
+    
+    //Verify the error list containd the expected string
+    member private this.VerifyErrorListContainedExpectedString(fileContents : string, expectedStr : string, ?addtlRefAssy : list<string>) =
+        let (solution, project, file) = this.CreateSingleFileProject(fileContents, ?references = addtlRefAssy)
+        
+        TakeCoffeeBreak(this.VS) // Wait for the background compiler to catch up.
+       
+        VerifyErrorListContainedExpectedStr(expectedStr,project)
+
+    //Verify error Count at specified file
+    member private this.VerifyCountAtSpecifiedFile(project : OpenProject ,num : int) = 
+        TakeCoffeeBreak(this.VS)
+        let errorList = GetErrors(project)
+        for error in errorList do
+            printfn "%A" error.Severity
+            printf "%s\n" (error.ToString()) 
+        if (num = errorList.Length) then 
+                ()
+            else
+                failwith "The error list number is not the expected %d" num
+    
+    [<Test>]
+    member public this.``OverloadsAndExtensionMethodsForGenericTypes``() = 
+        let fileContent = 
+            """
+open System.Linq
+
+type T = 
+    abstract Count : int -> bool
+    default this.Count(_ : int) = true
+
+    interface System.Collections.Generic.IEnumerable<int> with
+        member this.GetEnumerator() : System.Collections.Generic.IEnumerator<int> = failwith "not implemented"
+    interface System.Collections.IEnumerable with
+        member this.GetEnumerator() : System.Collections.IEnumerator = failwith "not implemented"
+
+let g (t : T) = t.Count()
+            """
+        this.VerifyNoErrorListAtOpenProject(fileContent)
+
+
+    [<Test>]
+    member public this.``ErrorsInScriptFile``() = 
+        let (solution, project, file) = this.CreateSingleFileProject("", fileKind = SourceFileKind.FSX)
+        
+        let checkErrors expected = 
+            let l = List.length (GetErrors project)
+            Assert.AreEqual(expected, l, "Unexpected number of errors in error list")
+        
+        TakeCoffeeBreak(this.VS)
+        checkErrors 0
+
+        ReplaceFileInMemory file <|
+            [
+                "#r \"System\""
+                "#r \"System2\""
+            ]
+        TakeCoffeeBreak(this.VS)
+        checkErrors 1
+
+        ReplaceFileInMemory file <|
+            [
+                "#r \"System\""
+            ]
+        TakeCoffeeBreak(this.VS)
+        checkErrors 0
+
+    [<Test>]
+    [<Ignore("GetErrors function doese not work for this case")>]
+    member public this.``LineDirective``() = 
+        use _guard = this.UsingNewVS()
+        let fileContents = """
+            # 100 "foo.fs"
+            let x = y """
+        let solution = this.CreateSolution()
+        let project = CreateProject(solution, "testproject")
+        let _ = AddFileFromTextBlob(project, "File1.fs", "namespace LineDirectives")
+        let _ = AddFileFromTextBlob(project,"File2.fs", fileContents)
+
+        let file = OpenFile(project, "File1.fs")
+        let _ = OpenFile(project,"File2.fs")
+        Assert.IsFalse(Build(project).BuildSucceeded)
+
+        this.VerifyCountAtSpecifiedFile(project,1)
+        VerifyErrorListContainedExpectedStr("The value or constructor 'y' is not defined",project)
+
+    [<Test>]
+    member public this.``InvalidConstructorOverload``() = 
+        let content = """
+        type X private() = 
+            new(_ : int) = X()
+            new(_ : bool) = X()
+            new(_ : float, _ : int) = X()
+        X(1.0)
+        """
+
+        let expectedMessages =
+            [
+        "Possible overload: 'new : bool -> X'. Type constraint mismatch. The type 
+    float    
+is not compatible with type
+    bool    
+The type 'float' is not compatible with the type 'bool'."
+        "Possible overload: 'new : int -> X'. Type constraint mismatch. The type 
+    float    
+is not compatible with type
+    int    
+The type 'float' is not compatible with the type 'int'."
+            ]
+            |> List.map (fun s -> s.Replace("\r\n", "\n"))
+
+        CheckErrorList content <|
+            fun errors ->
+                Assert.AreEqual(3, List.length errors)
+                assertContains errors "No overloads match for method 'X'. The available overloads are shown below (or in the Error List window)."
+                for expected in expectedMessages do
+                    assertContains errors expected
+
+    [<Test>]
+    member public this.``Query.InvalidJoinRelation.GroupJoin``() = 
+        let content = """
+let x = query { 
+    for x in [1] do
+    groupJoin y in [2] on ( x < y) into g
+    select x }
+        """
+        CheckErrorList content <|
+            fun errors ->
+                match errors with
+                | [err] ->
+                    Assert.AreEqual("Invalid join relation in 'groupJoin'. Expected 'expr <op> expr', where <op> is =, =?, ?= or ?=?.", err.Message)
+                | errs -> 
+                    Assert.Fail("Unexpected content of error list")
+
+    [<Test>]
+    member public this.``Query.NonOpenedNullableModule.Join``() = 
+        let content = """
+let t = 
+    query {
+        for x in [1] do
+        join y in [""] on (x ?=? y)
+        select 1  }
+        """
+        CheckErrorList content <|
+            fun errors ->
+                match errors with
+                | [err] ->
+                    Assert.AreEqual("The operator '?=?' cannot be resolved. Consider opening the module 'Microsoft.FSharp.Linq.NullableOperators'.", err.Message)
+                | errs -> 
+                    Assert.Fail("Unexpected content of error list")
+
+    [<Test>]
+    member public this.``Query.NonOpenedNullableModule.GroupJoin``() = 
+        let content = """
+let t = 
+    query {
+        for x in [1] do
+        groupJoin y in [""] on (x ?=? y) into g
+        select 1  }
+        """
+        CheckErrorList content <|
+            fun errors ->
+                match errors with
+                | [err] ->
+                    Assert.AreEqual("The operator '?=?' cannot be resolved. Consider opening the module 'Microsoft.FSharp.Linq.NullableOperators'.", err.Message)
+                | errs -> 
+                    Assert.Fail("Unexpected content of error list")
+
+
+    [<Test>]
+    member public this.``Query.InvalidJoinRelation.Join``() = 
+        let content = """
+let x = 
+    query {
+        for x in [1] do
+        join y in [""] on (x > y)
+        select 1
+    }
+    """
+        CheckErrorList content <|
+            fun errors ->
+                match errors with
+                | [err] ->
+                    Assert.AreEqual("Invalid join relation in 'join'. Expected 'expr <op> expr', where <op> is =, =?, ?= or ?=?.", err.Message)
+                | errs -> 
+                    Assert.Fail("Unexpected content of error list")
+
+    [<Test>]
+    member public this.``InvalidMethodOverload``() = 
+        let content = """
+        System.Console.WriteLine(null)
+        """
+        CheckErrorList content <|
+            fun errors ->
+                Assert.AreEqual(1, List.length errors)
+                assertContains errors "A unique overload for method 'WriteLine' could not be determined based on type information prior to this program point. A type annotation may be needed. Candidates: System.Console.WriteLine(buffer: char []) : unit, System.Console.WriteLine(format: string, params arg: obj []) : unit, System.Console.WriteLine(value: obj) : unit, System.Console.WriteLine(value: string) : unit"
+
+    [<Test>]
+    member public this.``InvalidMethodOverload2``() = 
+        let content = """
+type A<'T>() = 
+    member this.Do(a : int, b : 'T) = ()
+    member this.Do(a : int, b : int) = ()
+type B() = 
+    inherit A<int>() 
+
+let b = B()
+b.Do(1, 1)
+        """
+        CheckErrorList content <|
+            fun errors ->
+                Assert.AreEqual(1, List.length errors)
+                assertContains errors "A unique overload for method 'Do' could not be determined based on type information prior to this program point. A type annotation may be needed. Candidates: member A.Do : a:int * b:'T -> unit, member A.Do : a:int * b:int -> unit"
+
+    [<Test>]
+    member public this.``NoErrorInErrList``() = 
+        use _guard = this.UsingNewVS()
+        let fileContents1 = """
+            module NoErrors
+
+            open System.Collections.Generic
+            // but do not use it
+            """
+        let fileContents2 = """
+            // Regression test for FSHARP1.0:3824 - Problems with generic type parameters in type extensions (was: Confusing error/warning on type extension: code is less generic)
+            module NoErrors2
+
+            module DictionaryExtension = 
+
+                type System.Collections.Generic.IDictionary<'k,'v> with
+                    member this.TryLookup(key : 'k) =
+                        let mutable value = Unchecked.defaultof<'v>
+                        if this.TryGetValue(key, &value) then
+                            Some value
+                        else
+                            None
+
+            open DictionaryExtension"""
+        let solution = this.CreateSolution()
+        let project = CreateProject(solution,"testproject")
+        let _ = AddFileFromTextBlob(project,"File1.fs", fileContents1)
+        let _ = OpenFile(project,"File1.fs")
+        let _ = AddFileFromTextBlob(project,"File2.fs", fileContents2)
+        let _ = OpenFile(project,"File2.fs")
+        Build(project) |> ignore
+        TakeCoffeeBreak(this.VS)
+        this.VerifyCountAtSpecifiedFile(project,0)
+
+    [<Test>]
+    member public this.``NoLevel4Warning``() = 
+        use _guard = this.UsingNewVS()
+        let fileContents = """
+            namespace testerrorlist
+            module nolevel4warnings =
+                let x = System.DateTime.Now - System.DateTime.Now
+                x.Add(x) |> ignore """
+        let solution = this.CreateSolution()
+        let project = CreateProject(solution,"testproject")
+        let _ = AddFileFromTextBlob(project,"Module1.fs",fileContents)
+        
+        let _ = AddFileFromTextBlob(project,"Script.fsx","")
+        let _ = OpenFile(project,"Script.fsx")
+        Build(project) |> ignore
+
+        this.VerifyCountAtSpecifiedFile(project,0)
+        
+    [<Test>]
+    //This is an verify action test & example
+    member public this.``TestErrorMessage``() =
+        let fileContent = """Console.WriteLine("test")"""
+        let expectedStr = "The namespace or module 'Console' is not defined"
+        this.VerifyErrorListContainedExpectedString(fileContent,expectedStr)
+    
+    [<Test>]
+    member public this.``TestWrongKeywordInInterfaceImplementation``() = 
+        let fileContent = 
+            """
+type staticInInterface =
+    class
+        interface System.IDisposable with
+            static member Foo() = ()
+            member x.Dispose() = ()
+        end
+    end"""
+            
+        CheckErrorList fileContent <| function
+                | [err] -> Assert.IsTrue(err.Message.Contains("Unexpected keyword 'static' in member definition. Expected 'member', 'override' or other token"))
+                | x -> Assert.Fail(sprintf "Unexpected errors: %A" x)
+    
+    [<Test>]
+    [<Category("TypeProvider")>]
+    [<Category("TypeProvider.MultipleErrors")>]
+    member public this.``TypeProvider.MultipleErrors`` () =
+        let tpRef = System.IO.Path.Combine(System.Environment.CurrentDirectory,@"UnitTestsResources\MockTypeProviders\DummyProviderForLanguageServiceTesting.dll")
+        let checkList n = 
+            printfn "===TypeProvider.MultipleErrors: %d===" n
+            let content = sprintf "type Err = TPErrors.TP<%d>" n
+            let (solution, project, file) = this.CreateSingleFileProject(content, references = [tpRef])
+            TakeCoffeeBreak(this.VS)
+            let errorList = GetErrors(project)
+
+            for err in errorList do
+                printfn "Severity: %A, Message: %s" err.Severity err.Message
+
+            Assert.IsTrue(List.length errorList = n, "Unexpected size of error list")
+            let uniqueErrors = 
+                errorList 
+                |> Seq.map (fun m -> m.Message, m.Severity) 
+                |> set
+            Assert.IsTrue(uniqueErrors.Count = n, "List should not contain duplicate errors")
+            for x = 0 to (n - 1) do
+                let expectedName = sprintf "The type provider 'DummyProviderForLanguageServiceTesting.TypeProviderThatThrowsErrors' reported an error: Error %d" x
+                Assert.IsTrue(Set.contains (expectedName, Microsoft.VisualStudio.FSharp.LanguageService.Severity.Error) uniqueErrors)
+
+        for i = 1 to 10 do
+            checkList i
+
+    [<Test>]
+    [<Category("Records")>]
+    member public this.``Records.ErrorList.IncorrectBindings1``() = 
+        for code in [ "{_}"; "{_ = }"] do
+            printfn "checking %s" code
+            CheckErrorList code <|
+                fun errs ->
+                    printfn "%A" errs
+                    Assert.IsTrue((List.length errs) = 2)
+                    assertContains errs "Field bindings must have the form 'id = expr;'"
+                    assertContains errs "'_' cannot be used as field name"
+
+    [<Test>]
+    [<Category("Records")>]
+    member public this.``Records.ErrorList.IncorrectBindings2``() =
+        CheckErrorList "{_ = 1}" <|
+            function
+            | [err] -> Assert.AreEqual("'_' cannot be used as field name", err.Message)
+            | x -> printfn "%A" x; Assert.Fail("unexpected content of error list")
+
+    [<Test>]
+    [<Category("Records")>]
+    member public this.``Records.ErrorList.IncorrectBindings3``() =
+        CheckErrorList "{a = 1; _; _ = 1}" <|
+            fun errs -> 
+                Assert.IsTrue((List.length errs) = 3)
+                let groupedErrs = errs |> Seq.groupBy (fun e -> e.Message) |> Seq.toList
+                Assert.IsTrue((List.length groupedErrs) = 2)
+                for (msg, e) in groupedErrs do
+                    if msg = "'_' cannot be used as field name" then Assert.AreEqual(2, Seq.length e)
+                    elif msg = "Field bindings must have the form 'id = expr;'" then Assert.AreEqual(1, Seq.length e)
+                    else Assert.Fail (sprintf "Unexpected message %s" msg)
+
+
+    [<Test>]
+    [<Category("TypeProvider")>]
+    [<Category("TypeProvider.StaticParameters")>]
+    //This test case Verify the Error List shows the correct error message when the static parameter type is invalid
+    //Intent: We want to make sure that both errors coming from the TP and the compilation of things specific to type provider are properly flagged in the error list.
+    member public this.``TypeProvider.StaticParameters.IncorrectType `` () =
+        // dummy Type Provider exposes a parametric type (N1.T) that takes 2 static params (string * int) 
+        // but here as you can see it's give (int * int)
+        let fileContent = """ type foo = N1.T< const 42,2>"""
+        let expectedStr = """This expression was expected to have type
+    string    
+but here has type
+    int    """
+        this.VerifyErrorListContainedExpectedString(fileContent,expectedStr,
+            addtlRefAssy = [System.IO.Path.Combine(System.Environment.CurrentDirectory,@"UnitTestsResources\MockTypeProviders\DummyProviderForLanguageServiceTesting.dll")])
+    
+    [<Test>]
+    [<Category("TypeProvider")>]
+    [<Category("TypeProvider.StaticParameters")>]
+    [<Ignore("This is ignored because currently the Mock Type Provider is not evaluating the static parameter.")>]
+    //This test case Verify the Error List shows the correct error message when applying invalid static parameter to the provided type
+    member public this.``TypeProvider.StaticParameters.Incorrect `` () =
+        
+        // dummy Type Provider exposes a parametric type (N1.T) that takes 2 static params (string * int) 
+        let fileContent = """ type foo = N1.T< const " ",2>"""
+        let expectedStr = "An error occurred applying the static arguments to a provided type"
+       
+        this.VerifyErrorListContainedExpectedString(fileContent,expectedStr,
+            addtlRefAssy = [System.IO.Path.Combine(System.Environment.CurrentDirectory,@"UnitTestsResources\MockTypeProviders\DummyProviderForLanguageServiceTesting.dll")])
+   
+    [<Test>]
+    [<Category("TypeProvider")>]
+    [<Category("TypeProvider.StaticParameters")>]
+    //This test case Verify that Error List shows the correct error message when Type Provider that takes two static parameter is given only one static parameter.
+    member public this.``TypeProvider.StaticParameters.IncorrectNumberOfParameter  `` () =
+        
+        // dummy Type Provider exposes a parametric type (N1.T) that takes 2 static params (string * int) 
+        // but here as you can see it's give (string)
+        let fileContent = """type foo = N1.T< const "Hello World">"""
+        let expectedStr = "The static parameter 'ParamIgnored' of the provided type 'T' requires a value. Static parameters to type providers may be optionally specified using named arguments, e.g. 'T<ParamIgnored=...>'."
+       
+        this.VerifyErrorListContainedExpectedString(fileContent,expectedStr,
+            addtlRefAssy = [System.IO.Path.Combine(System.Environment.CurrentDirectory,@"UnitTestsResources\MockTypeProviders\DummyProviderForLanguageServiceTesting.dll")])
+    [<Test>]
+    [<Category("TypeProvider")>]
+    member public this.``TypeProvider.ProhibitedMethods`` () =
+        let cases = 
+            [
+                "let x = BadMethods.Arr.GetFirstElement([||])", "Get"
+                "let y = BadMethods.Arr.SetFirstElement([||], 5)", "Set"
+                "let z = BadMethods.Arr.AddressOfFirstElement([||])", "Address"
+            ]
+        for (code, str) in cases do
+            this.VerifyErrorListContainedExpectedString
+                (
+                    code,
+                    sprintf "Array method '%s' is supplied by the runtime and cannot be directly used in code." str,
+                    addtlRefAssy = [System.IO.Path.Combine(System.Environment.CurrentDirectory,@"UnitTestsResources\MockTypeProviders\DummyProviderForLanguageServiceTesting.dll")]
+                )    
+    
+    [<Test>]
+    [<Category("TypeProvider")>]
+    [<Category("TypeProvider.StaticParameters")>]
+    //This test case verify that the Error list count is one in the Error list item when given invalid static parameter that raises an error.
+    member public this.``TypeProvider.StaticParameters.ErrorListItem `` () =
+        
+         this.VerifyErrorListCountAtOpenProject(
+            fileContents = """
+                            type foo = N1.T< const "Hello World",2>""",
+            num = 1) 
+    
+    [<Test>]
+    [<Category("TypeProvider")>]
+    [<Category("TypeProvider.StaticParameters")>]
+    //This test case Verify that the Warning list count is one in the Warning list item when there is incorrect indentation in the code.
+    member public this.``TypeProvider.StaticParameters.WarningListItem `` () =
+        
+         this.VerifyWarningListCountAtOpenProject(
+            fileContents = """
+                            type foo = N1.T< 
+                                const "Hello World",2>""",
+            expectedNum = 1,
+            addtlRefAssy = [System.IO.Path.Combine(System.Environment.CurrentDirectory,@"UnitTestsResources\MockTypeProviders\DummyProviderForLanguageServiceTesting.dll")]) 
+    
+    [<Test>]
+    [<Category("TypeProvider")>]
+    [<Category("TypeProvider.StaticParameters")>]
+    //This test case Verify that there is No Error list count in the Error list item when the file content is correct.
+    member public this.``TypeProvider.StaticParameters.NoErrorListCount `` () =
+                 
+         this.VerifyNoErrorListAtOpenProject(
+            fileContents = """
+                            type foo = N1.T< const "Hello World",2>""",
+            addtlRefAssy = [System.IO.Path.Combine(System.Environment.CurrentDirectory,@"UnitTestsResources\MockTypeProviders\DummyProviderForLanguageServiceTesting.dll")]) 
+    
+
+    [<Test>]
+    member public this.``NoError.FlagsAndSettings.TargetOptionsRespected``() =
+        let fileContent = """
+            [<System.Obsolete("x")>]
+            let fn x = 0
+            let y = fn 1"""
+        // Turn off the "Obsolete" warning.
+        let (solution, project, file) = this.CreateSingleFileProject(fileContent, disabledWarnings = ["44"])
+
+        TakeCoffeeBreak(this.VS) // Wait for the background compiler to catch up.
+        let errorList = GetErrors(project)
+        Assert.IsTrue(errorList.IsEmpty)
+
+    [<Test>]
+    member public this.``UnicodeCharactors``() = 
+        use _guard = this.UsingNewVS()
+        let solution = this.CreateSolution()
+        let project = CreateProject(solution,"新規baApplication5")
+        let _ = AddFileFromTextBlob(project,"新規baProgram.fsi","")       
+        let _ = AddFileFromTextBlob(project,"新規bcrogram.fs","")
+
+        let file = OpenFile(project,"新規baProgram.fsi")  
+        let file = OpenFile(project,"新規bcrogram.fs") 
+
+        Assert.IsFalse(Build(project).BuildSucceeded)
+        Assert.IsTrue(GetErrors(project) 
+                        |> List.exists(fun error -> (error.ToString().Contains("新規baProgram")))) 
+
+    // In this bug, particular warns were still present after nowarn        
+    [<Test>]
+    [<Category("PerfCheck")>]
+    member public this.``NoWarn.Bug5424``() =  
+        let fileContent = """
+            #nowarn "67" // this type test or downcast will always hold
+            #nowarn "66" // this upcast is unnecessary - the types are identical
+            namespace Namespace1
+                module Test =
+                    open System
+                    let a = ((5 :> obj) :?> Object)
+                    let b = a :> obj"""
+        this.VerifyNoErrorListAtOpenProject(fileContent)
+
+    /// FEATURE: Errors in flags are sent in Error list.
+    [<Test>]
+    member public this.``FlagsAndSettings.ErrorsInFlagsDisplayed``() =  
+        use _guard = this.UsingNewVS()
+        let solution = this.CreateSolution()
+        let project = CreateProject(solution,"testproject")
+        SetVersionFile(project,"nonexistent")
+        let file = AddFileFromText(project,"File1.fs",["#light"])
+        let file = OpenFile(project,"File1.fs")            
+        TakeCoffeeBreak(this.VS) // Wait for the background compiler to catch up.
+        VerifyErrorListContainedExpectedStr("nonexistent",project)
+
+    [<Test>]
+    member public this.``ErrorReporting.WrongPreprocessorIf``() =  
+        let fileContent = """
+            #light
+            #if !!!!COMPILED
+            #endif"""
+        this.VerifyErrorListContainedExpectedString(fileContent,"#if")
+
+    [<Test>]
+    member public this.``BackgroundComplier``() = 
+        this.VerifyErrorListCountAtOpenProject(
+            fileContents = """
+                #light
+
+                module Test
+
+                module M =
+                    let func (args : string[]) = 
+                        if(args.Length=1 && args.[0]="Hello") then 0 else 1
+
+                    [<EntryPoint>]
+                    let main2 args =
+                        let res = func(args)
+                        exit(res)
+       
+                    let f x = 
+                        let p = x
+                        p + 1
+                
+                    let g x = 
+                        let p = x
+                        p + 1
+                    """,
+            num = 2)
+
+    [<Test>]
+    member public this.``CompilerErrorsInErrList1``() = 
+        this.VerifyErrorListCountAtOpenProject(
+            fileContents = """
+                namespace Errorlist
+                module CompilerError =
+        
+                    let a = NoVal""",
+            num = 1 )
+
+    [<Test>]
+    member public this.``CompilerErrorsInErrList4``() = 
+        this.VerifyNoErrorListAtOpenProject(
+            fileContents = """
+                #nowarn "47"
+
+                type Fruit (shelfLife : int) as x =
+    
+                        let mutable m_age = (fun () -> x)
+
+
+                #nowarn "25" // FS0025: Incomplete pattern matches on this expression. For example, the value 'C' 
+
+                type DU = A | B | C
+                let f x = function A -> true | B -> false
+
+
+                #nowarn "58" // FS0058: possible incorrect indentation: this token is offside of context started at
+  
+                let _fsyacc_gotos = [| 
+                0us; 
+                1us;
+                2us
+                |] """ )
+
+    [<Test>]
+    member public this.``CompilerErrorsInErrList5``() = 
+        this.VerifyErrorListCountAtOpenProject(
+            fileContents = """                
+                #r "D:\x\Absent.dll"
+
+                let x = 0 """,
+            num = 1)
+
+    [<Test>]
+    member public this.``CompilerErrorsInErrList6``() = 
+        this.VerifyErrorListCountAtOpenProject(
+            fileContents = """               
+                type EnumOfBigInt =
+                    | A = 0I
+                    | B = 0I
+
+                type EnumOfNatNum =
+                    | A = 0N
+                    | B = 0N """,
+            num = 2)
+
+    [<Test>]
+    member public this.``CompilerErrorsInErrList7``() = 
+        this.VerifyErrorListCountAtOpenProject(
+            fileContents = """               
+                // FSB 1124, Implement constant literals
+                type EnumType =
+                    | A = 1
+                    | B = 2
+
+                type CustomAttrib(a:int, b:string, c:float, d:EnumType) =
+                    inherit System.Attribute()
+    
+                //[<Literal>]    
+                let a = 42
+                //[<Literal>]
+                let b = "str"
+                //[<Literal>]
+                let c = 3.141
+                //[<Literal>]
+                let d = EnumType.A
+
+                [<CustomAttrib(a, b, c, d)>]
+                type SomeClass() =
+                    override this.ToString() = "SomeClass"
+
+                [<EntryPoint>]
+                let main0 args = ()
+
+                let foo = 1 """,
+            num = 5)
+
+    [<Test>]
+    member public this.``CompilerErrorsInErrList8``() = 
+        this.VerifyErrorListCountAtOpenProject(
+            fileContents = """              
+                type EnumInt8s      = | A1 = - 10y """ ,
+            num = 1 )
+
+    [<Test>]
+    member public this.``CompilerErrorsInErrList9``() = 
+        use _guard = this.UsingNewVS()
+        let fileContents1 = """
+            namespace NS
+                [<AbstractClass>]
+                type Lib() =
+                    class
+                        abstract M : int -> int
+                    end """
+        let fileContents2 = """
+            namespace NS
+                module M = 
+                    type Lib with
+                        override x.M i = i
+            """
+        let solution = this.CreateSolution()
+        let project = CreateProject(solution,"testproject")
+        let _ = AddFileFromTextBlob(project,"File1.fs",fileContents1)
+        let file1 = OpenFile(project,"File1.fs")
+        let _ = AddFileFromTextBlob(project,"File2.fs",fileContents2)
+        let file2 = OpenFile(project,"File2.fs")
+        //this.VerifyErrorListNumberAtOpenProject
+        this.VerifyCountAtSpecifiedFile(project,1)
+        TakeCoffeeBreak(this.VS)
+        Build(project) |> ignore
+        this.VerifyCountAtSpecifiedFile(project,1)
+
+    [<Test>]
+    member public this.``CompilerErrorsInErrList10``() = 
+        let fileContents = """
+            namespace Errorlist
+            module CompilerError =
+            
+                printfn "%A" System.Windows.Forms.Application.UserAppDataPath """
+        let (_, project, _) = this.CreateSingleFileProject(fileContents, references = ["PresentationCore.dll"; "PresentationFramework.dll"])
+        Build(project) |> ignore
+
+        this.VerifyCountAtSpecifiedFile(project,1)
+
+    [<Test>]
+    member public this.``DoubleClickErrorListItem``() = 
+        this.VerifyErrorListCountAtOpenProject(
+            fileContents = """
+                let x = x """,
+            num = 1)
+
+    [<Test>]
+    member public this.``FixingCodeAfterBuildRemovesErrors01``() = 
+        this.VerifyErrorListCountAtOpenProject(
+            fileContents = """
+                let x = 4 + "x" """,
+            num = 2)
+
+    [<Test>]
+    member public this.``FixingCodeAfterBuildRemovesErrors02``() = 
+        this.VerifyNoErrorListAtOpenProject(
+            fileContents = "let x = 4" )   
+                                 
+    [<Test>]
+    member public this.``IncompleteExpression``() = 
+        this.VerifyErrorListCountAtOpenProject(
+            fileContents = """
+                // Regresson test for FSHARP1.0:1397 - Warning required on expr of function type who result is immediately thrown away
+                module Test
+
+                printfn "%A"
+
+                List.map (fun x -> x + 1) """ ,
+            num = 2)
+
+    [<Test>]
+    member public this.``IntellisenseRequest``() = 
+        this.VerifyErrorListCountAtOpenProject(
+            fileContents = """
+                type Foo() =
+                    member a.B(*Marker*) : int = "1" """,
+            num = 1)
+
+    [<Test>]
+    member public this.``TypeChecking1``() = 
+        this.VerifyErrorListCountAtOpenProject(
+            fileContents = """
+                open System
+
+                module Foo  =
+                    type Thread(thread) =
+                        let mutable next : Thread option = thread
+                        member t.Next with get() = next and set(thread) = next - thread
+
+                module Bar = 
+                    let x = new Foo.Thread(None)
+
+                    x.Next <- Some x  """,
+            num = 1)
+            
+    [<Test>]
+    member public this.``TypeChecking2``() = 
+        this.VerifyErrorListContainedExpectedString(
+            fileContents = """
+                open System
+
+                module Foo  =
+                    type Thread(thread) =
+                        let mutable next : Thread option = thread
+                        member t.Next with get() = next and set(thread) = next - thread
+
+                module Bar = 
+                    let x = new Foo.Thread(None)
+
+                    x.Next <- Some x  """,
+            expectedStr = "Foo.Thread option")
+            
+    [<Test>]
+    member public this.``TypeChecking3``() = 
+        this.VerifyErrorListCountAtOpenProject(
+            fileContents = """
+                open System
+
+                module Foo  =
+                    type Thread(thread) =
+                        let mutable next : Thread option = thread
+                        member t.Next with get() = next and set(thread) = next - thread
+
+                module Bar = 
+                    let x = new Foo.Thread(None)
+                    x.Next <- Some 1 """,
+            num = 1)
+            
+    [<Test>]
+    member public this.``TypeChecking4``() = 
+        this.VerifyErrorListContainedExpectedString(
+            fileContents = """
+                open System
+
+                module Foo  =
+                    type Thread(thread) =
+                        let mutable next : Thread option = thread
+                        member t.Next with get() = next and set(thread) = next - thread
+
+                module Bar = 
+                    let x = new Foo.Thread(None)
+                    x.Next <- Some 1 """,
+            expectedStr = "operator '-'" )
+                
+(* TODO why does this portion not work?  specifically, last assert fails 
+        printfn "changing file..."
+        ReplaceFileInMemory file1 ["#light"
+                                   "let xx = \"foo\""   // now x is string
+                                   "printfn \"hi\""]
+
+        // assert p1 xx is string
+        MoveCursorToEndOfMarker(file1,"let x")
+        TakeCoffeeBreak(this.VS) 
+        let tooltip = GetQuickInfoAtCursor file1
+        AssertContains(tooltip,"string")
+
+        // assert p2 yy is int
+        MoveCursorToEndOfMarker(file2,"let y")
+        let tooltip = GetQuickInfoAtCursor file2
+        AssertContains(tooltip,"int")
+
+        AssertNoErrorsOrWarnings(project1)
+        AssertNoErrorsOrWarnings(project2)
+
+        printfn "rebuilding dependent project..."
+        // (re)build p1 (with xx now string)
+        Build(project1) |> ignore
+        TakeCoffeeBreak(this.VS) 
+
+        AssertNoErrorsOrWarnings(project1)
+        AssertNoErrorsOrWarnings(project2)
+
+        // assert p2 yy is now string
+        MoveCursorToEndOfMarker(file2,"let y")
+        let tooltip = GetQuickInfoAtCursor file2
+        AssertContains(tooltip,"string")
+*)
+
+    [<Test>]
+    member public this.``Warning.ConsistentWithLanguageService``() =  
+        let fileContent = """
+            open System
+            atomic atomic atomic atomic atomic atomic atomic atomic atomic atomic
+            atomic atomic atomic atomic atomic atomic atomic atomic atomic atomic"""
+        let (_, project, file) = this.CreateSingleFileProject(fileContent, fileKind = SourceFileKind.FSX)
+        TakeCoffeeBreak(this.VS) // Wait for the background compiler to catch up.
+        let warnList = GetWarnings(project)
+        Assert.AreEqual(20,warnList.Length)
+
+    [<Test>]
+    member public this.``Warning.ConsistentWithLanguageService.Comment``() =  
+        let fileContent = """
+            open System
+            //atomic atomic atomic atomic atomic atomic atomic atomic atomic atomic
+            //atomic atomic atomic atomic atomic atomic atomic atomic atomic atomic"""
+        let (_, project, file) = this.CreateSingleFileProject(fileContent, fileKind = SourceFileKind.FSX)
+        TakeCoffeeBreak(this.VS) // Wait for the background compiler to catch up.
+        let warnList = GetWarnings(project)
+        Assert.AreEqual(0,warnList.Length)
+
+    [<Test>]
+    [<Ignore("GetErrors function doese not work for this case")>]
+    member public this.``Errorlist.WorkwithoutNowarning``() =  
+        let fileContent = """
+            type Fruit (shelfLife : int) as x =
+                let mutable m_age = (fun () -> x)
+            #nowarn "47"
+            """
+        let (_, project, file) = this.CreateSingleFileProject(fileContent)
+
+        Assert.IsTrue(Build(project).BuildSucceeded)
+        TakeCoffeeBreak(this.VS)
+        let warnList = GetErrors(project)
+        Assert.AreEqual(1,warnList.Length) 
+        
+//Allow the ErrorListTests run under different context
+namespace UnitTests.Tests.LanguageService.ErrorList
+open UnitTests.Tests.LanguageService
+open UnitTests.TestLib.LanguageService
+open UnitTests.TestLib.ProjectSystem
+open NUnit.Framework
+open Salsa.Salsa
+
+// context msbuild
+[<TestFixture>] 
+[<Category("LanguageService.MSBuild")>]
+type ``MSBuild`` = 
+   inherit ErrorListTests
+   new() = { inherit ErrorListTests(VsOpts = fst (Models.MSBuild())); }
+
+// Context project system
+[<TestFixture>] 
+[<Category("LanguageService.ProjectSystem")>]
+type ``ProjectSystem`` = 
+    inherit ErrorListTests
+    new() = { inherit ErrorListTests(VsOpts = LanguageServiceExtension.ProjectSystem); } 
diff --git a/vsintegration/src/unittests/Tests.LanguageService.ErrorRecovery.fs b/vsintegration/src/unittests/Tests.LanguageService.ErrorRecovery.fs
new file mode 100644
index 0000000..e5fbebb
--- /dev/null
+++ b/vsintegration/src/unittests/Tests.LanguageService.ErrorRecovery.fs
@@ -0,0 +1,286 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+namespace UnitTests.Tests.LanguageService
+
+open System
+open System.IO
+open NUnit.Framework
+open Salsa.Salsa
+open Salsa.VsOpsUtils
+open UnitTests.TestLib.Salsa
+open UnitTests.TestLib.Utils
+open UnitTests.TestLib.LanguageService
+
+type ErrorRecoveryTests()  = 
+    inherit LanguageServiceBaseTests()
+
+    //Verify the error list containd the expected string
+    member private this.VerifyErrorListContainedExpectedString(fileContents : string, expectedStr : string) =
+        let (solution, project, file) = this.CreateSingleFileProject(fileContents)       
+        let errorList = GetErrors(project)
+        let GetErrorMessages(errorList : Error list) =
+            [ for i = 0 to errorList.Length - 1 do
+                yield errorList.[i].Message]
+            
+        Assert.IsTrue(errorList
+                          |> GetErrorMessages
+                          |> Seq.exists (fun errorMessage ->
+                                errorMessage.Contains(expectedStr)))
+
+   // Not a recovery case, but make sure we get a squiggle at the unfinished Main()
+    [<Test>]
+    [<Category("error_recovery")>]
+    member public this.``ErrorRecovery.Bug4538_3``() = 
+        let fileContent = """
+            type MyType() = 
+                override x.ToString() = ""
+            let Main() =
+                let x = MyType()"""
+        let expectedStr = "Block following this 'let' is unfinished"
+        this.VerifyErrorListContainedExpectedString(fileContent,expectedStr)
+
+    // Not a recovery case, but make sure we get a squiggle at the unfinished Main()
+    [<Test>]
+    [<Category("error_recovery")>]
+    member public this.``ErrorRecovery.Bug4538_4``() =  
+        let fileContent = """
+            type MyType() = 
+                override x.ToString() = ""
+            let Main() =
+                use x = MyType()"""
+        let expectedStr = "Block following this 'use' is unfinished"
+        this.VerifyErrorListContainedExpectedString(fileContent,expectedStr)
+
+    [<Test>]
+    [<Category("error_recovery")>]
+    [<Category("PerfCheck")>]
+    member public this.``ErrorRecovery.Bug4881_1``() =  
+        let code = 
+                                    ["let s = \"\""
+                                     "if true then"
+                                     "    ()"
+                                     "elif s."   
+                                     "else ()"
+                                     ]
+        let (_, _, file) = this.CreateSingleFileProject(code, fileKind = SourceFileKind.FSX)
+        MoveCursorToEndOfMarker(file,"elif s.")
+        TakeCoffeeBreak(this.VS)
+        let completions = AutoCompleteAtCursor file
+        AssertCompListContains(completions,"Split")       
+        
+    [<Test>]
+    [<Category("error_recovery")>]
+    member public this.``ErrorRecovery.Bug4881_2``() =  
+        let code =
+                                    ["let s = \"\""
+                                     "if true then"
+                                     "    ()"
+                                     "elif true"   
+                                     "elif s."   
+                                     "else ()"
+                                     ]
+        let (_, _, file) = this.CreateSingleFileProject(code, fileKind = SourceFileKind.FSX)
+        MoveCursorToEndOfMarker(file,"elif s.")
+        TakeCoffeeBreak(this.VS)
+        let completions = AutoCompleteAtCursor file
+        AssertCompListContains(completions,"Split")      
+
+    [<Test>]
+    [<Category("error_recovery")>]
+    member public this.``ErrorRecovery.Bug4881_3``() =  
+        let code = 
+                                    ["let s = \"\""
+                                     "if true then"
+                                     "    ()"
+                                     "elif s."   
+                                     "elif true"   
+                                     "else ()"
+                                     ]
+        let (_, _, file) = this.CreateSingleFileProject(code, fileKind = SourceFileKind.FSX)
+        MoveCursorToEndOfMarker(file,"elif s.")
+        TakeCoffeeBreak(this.VS)
+        let completions = AutoCompleteAtCursor file
+        AssertCompListContains(completions,"Split")  
+        
+
+    [<Test>]
+    [<Category("error_recovery")>]
+    member public this.``ErrorRecovery.Bug4881_4``() =  
+        let code = 
+                                    ["let s = \"\""
+                                     "if true then"
+                                     "    ()"
+                                     "elif s."   
+                                     ]
+        let (_, _, file) = this.CreateSingleFileProject(code, fileKind = SourceFileKind.FSX)
+        MoveCursorToEndOfMarker(file,"elif s.")
+        TakeCoffeeBreak(this.VS)
+        let completions = AutoCompleteAtCursor file
+        AssertCompListContains(completions,"Split")    
+        
+        
+    // This case was fixed while investigating 4538.            
+    [<Test>]
+    [<Category("error_recovery")>]
+    member public this.``ErrorRecovery.NotFixing4538_1``() =  
+        let code = 
+                                    ["type MyType() = "
+                                     "    override x.ToString() = \"\""
+                                     "let Main() ="
+                                     "    let _ = new MyT"
+                                     "    ()"
+                                     ]
+        let (_, _, file) = this.CreateSingleFileProject(code, fileKind = SourceFileKind.FSX)
+        MoveCursorToEndOfMarker(file,"new MyT")
+        TakeCoffeeBreak(this.VS)
+        let completions = CtrlSpaceCompleteAtCursor file
+        AssertCompListContains(completions,"MyType")
+        
+    // This case was fixed while investigating 4538.            
+    [<Test>]
+    [<Category("error_recovery")>]
+    member public this.``ErrorRecovery.NotFixing4538_2``() =  
+        let code =
+                                    ["type MyType() = "
+                                     "    override x.ToString() = \"\""
+                                     "let Main() ="
+                                     "    let _ = MyT"
+                                     "    ()"
+                                     ]
+        let (_, _, file) = this.CreateSingleFileProject(code, fileKind = SourceFileKind.FSX)
+        MoveCursorToEndOfMarker(file,"= MyT")
+        TakeCoffeeBreak(this.VS)
+        let completions = CtrlSpaceCompleteAtCursor file
+        AssertCompListContains(completions,"MyType")
+        
+    // This case was fixed while investigating 4538.            
+    [<Test>]
+    [<Category("error_recovery")>]
+    member public this.``ErrorRecovery.NotFixing4538_3``() =  
+        let code = 
+                                    ["type MyType() = "
+                                     "    override x.ToString() = \"\""
+                                     "let Main() ="
+                                     "    let _ = MyT"
+                                     ]
+        let (_, _, file) = this.CreateSingleFileProject(code, fileKind = SourceFileKind.FSX)
+        MoveCursorToEndOfMarker(file,"= MyT")
+        TakeCoffeeBreak(this.VS)
+        let completions = CtrlSpaceCompleteAtCursor file
+        AssertCompListContains(completions,"MyType")
+        
+    [<Test>]
+    [<Category("error_recovery")>]
+    member public this.``ErrorRecovery.Bug4538_1``() =  
+        let code = 
+                                    ["type MyType() = "
+                                     "    override x.ToString() = \"\""
+                                     "let Main() ="
+                                     "    let _ = MyT"
+                                     ]
+        let (_, _, file) = this.CreateSingleFileProject(code, fileKind = SourceFileKind.FSX)
+        
+        MoveCursorToEndOfMarker(file,"= MyT")
+        TakeCoffeeBreak(this.VS)
+        let completions = CtrlSpaceCompleteAtCursor file
+        AssertCompListContains(completions,"MyType")    
+        
+    [<Test>]
+    [<Category("error_recovery")>]
+    member public this.``ErrorRecovery.Bug4538_2``() =  
+        let code = 
+                                    ["type MyType() = "
+                                     "    override x.ToString() = \"\""
+                                     "let Main() ="
+                                     "    let x = MyType()"
+                                     "    let _ = MyT"
+                                     ]
+        let (_, _, file) = this.CreateSingleFileProject(code, fileKind = SourceFileKind.FSX)
+        MoveCursorToEndOfMarker(file,"_ = MyT")
+        TakeCoffeeBreak(this.VS)
+        let completions = CtrlSpaceCompleteAtCursor file
+        AssertCompListContains(completions,"MyType")  
+        
+
+        
+      
+        
+    [<Test>]
+    [<Category("error_recovery")>]
+    member public this.``ErrorRecovery.Bug4538_5``() =  
+        let code = 
+                                    ["type MyType() = "
+                                     "    override x.ToString() = \"\""
+                                     "let Main() ="
+                                     "    use x = null"
+                                     "    use _ = MyT"
+                                     ]
+        let (_, _, file) = this.CreateSingleFileProject(code, fileKind = SourceFileKind.FSX)
+        MoveCursorToEndOfMarker(file,"_ = MyT")
+        TakeCoffeeBreak(this.VS)
+        let completions = CtrlSpaceCompleteAtCursor file
+        AssertCompListContains(completions,"MyType")          
+        
+        
+    [<Test>]
+    [<Category("error_recovery")>]
+    member public this.``ErrorRecovery.Bug4594_1``() =  
+        let code = 
+                                    ["let Bar(xyz) ="
+                                     "    let hello ="
+                                     "        if x"
+                                     ]
+        let (_, _, file) = this.CreateSingleFileProject(code, fileKind = SourceFileKind.FSX)
+        MoveCursorToEndOfMarker(file,"if x")
+        TakeCoffeeBreak(this.VS)
+        let completions = CtrlSpaceCompleteAtCursor file
+        AssertCompListContains(completions,"xyz")     
+
+    /// In this bug, the Module. at the very end of the file was treated as if it were in the scope
+    /// of Module rather than right after it. This check just makes sure we can see a data tip because
+    /// Module is available.
+    [<Test>]
+    member public this.``ErrorRecovery.5878_1``() =
+        Helper.AssertMemberDataTipContainsInOrder
+            (this.TestRunner,
+            (*code *)
+              [
+               "module Module ="
+               "    /// Union comment"
+               "    type Union ="
+               "        /// Case comment"
+               "        | Case of int"
+               "Module."
+               ] ,
+             (* marker *)
+             "Module.",
+             (* completed item *)             
+             "Case", 
+             (* expect to see in order... *)
+             [
+              "union case Module.Union.Case: int -> Module.Union";
+              "Case comment";
+             ]
+            )
+
+//Allow the TimeStampTests run under different context
+namespace UnitTests.Tests.LanguageService.ErrorRecovery
+open UnitTests.Tests.LanguageService
+open UnitTests.TestLib.LanguageService
+open UnitTests.TestLib.ProjectSystem
+open NUnit.Framework
+open Salsa.Salsa
+
+// context msbuild
+[<TestFixture>] 
+[<Category("LanguageService.MSBuild")>]
+type ``MSBuild`` = 
+   inherit ErrorRecoveryTests
+   new() = { inherit ErrorRecoveryTests(VsOpts = fst (Models.MSBuild())); }
+
+// Context project system
+[<TestFixture>] 
+[<Category("LanguageService.ProjectSystem")>]
+type ``ProjectSystem`` = 
+    inherit ErrorRecoveryTests
+    new() = { inherit ErrorRecoveryTests(VsOpts = LanguageServiceExtension.ProjectSystem); } 
\ No newline at end of file
diff --git a/vsintegration/src/unittests/Tests.LanguageService.F1Keyword.fs b/vsintegration/src/unittests/Tests.LanguageService.F1Keyword.fs
new file mode 100644
index 0000000..5f8b03d
--- /dev/null
+++ b/vsintegration/src/unittests/Tests.LanguageService.F1Keyword.fs
@@ -0,0 +1,392 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+namespace UnitTests.Tests.LanguageService
+
+open System
+open NUnit.Framework
+open Salsa.Salsa
+open Salsa.VsOpsUtils
+open UnitTests.TestLib.Salsa
+open UnitTests.TestLib.Utils
+open UnitTests.TestLib.LanguageService
+
+type F1KeywordTests() =
+    inherit LanguageServiceBaseTests()
+
+    member private this.TestF1Keywords(expectedKeywords, testLines, ?addtlRefAssy : list<string>) =
+        let lines, poslist = // poslist is in _cursor_ postions. Cursor postions are 1-based.
+            let rec extractPos (col:int) row (s:string) poslist =
+                    let next = s.IndexOf("$", col)
+                    if next < 0 then
+                        s, poslist
+                    else                     
+                        let s = s.Remove(next, 1)
+                        extractPos next row s ((row,next+1)::poslist)
+            let _, l, p =
+                List.fold (fun (row,lines,poslist) s -> 
+                                let (s', poslist') = extractPos 0 row s poslist
+                                (row+1, (s'::lines),poslist')) (1,[],[]) testLines 
+            List.rev l , List.rev p
+
+        let refs = 
+            let standard = ["mscorlib"; "System"; "System.Core"]
+            match addtlRefAssy with
+            | Some r -> standard @ r
+            | _ -> standard
+
+        let (_,_, file) = this.CreateSingleFileProject(lines, references = refs)
+        Assert.IsTrue(List.length expectedKeywords = List.length poslist, sprintf "number of keywords (%d) does not match positions (%d)" (List.length expectedKeywords) (List.length poslist))
+        List.iter2 
+            (fun expectedKeyword (row,col) ->
+                MoveCursorTo(file,row,col)
+                let keyword = GetF1KeywordAtCursor file
+                Assert.AreEqual(expectedKeyword, keyword)) expectedKeywords poslist
+        ()
+        
+    [<Test>]
+    [<Category("PerfCheck")>]
+    member public this.``NoKeyword.Negative`` () =
+        let file =
+            [   "let s  = \"System.Con$sole\""
+                "let n = 999$99"
+                "#if UNDEFINED"
+                " let w = List.re$v []"
+                "#endif"
+            ]
+        let keywords = [ None; None; None ] 
+        this.TestF1Keywords(keywords, file)
+    
+    [<Test>]
+    member public this.``Preprocessor`` () =
+        let file =
+            [   "#i$f foobaz"
+                "#e$ndif"
+            ]
+        let keywords = [ Some "#if_FS"; Some "#endif_FS" ] 
+        this.TestF1Keywords(keywords, file)
+
+    [<Test>]
+    member public this.``Regression.DotNetMethod.854364``()  =
+        let file =
+            [   "let i : int = 42"
+                "i.ToStri$ng()"
+                "i.ToStri$ng(\"format\")"
+            ]
+        let keywords = 
+            [   Some "System.Int32.ToString"
+                Some "System.Int32.ToString"
+            ]
+        this.TestF1Keywords(keywords, file)
+        
+    [<Test>]
+    member public this.``Namespaces`` () =
+        let file =
+            [   "open Syst$em.N$et"
+                "open System.I$O"
+                "open Microsoft.FSharp.Core"
+                ""    
+                "System.Cons$ole.WriteLine()"
+            ]     
+        let keywords =
+            [   Some "System"
+                Some "System.Net"
+                Some "System.IO"
+                Some "System.Console"
+            ]
+        this.TestF1Keywords(keywords, file)
+
+    [<Test>]
+    member public this.``Namespaces.BeforeDot`` () =
+        let file =
+            [   "open System$.Net$"
+                "open System$.IO"
+                "open System$.Collections$.Generic$"
+                "open Microsoft.FSharp.Core"
+                ""    
+                "System$.Console$.WriteLine()"
+            ]     
+        let keywords =
+            [   Some "System"
+                Some "System.Net"                
+                Some "System"
+                Some "System"
+                Some "System.Collections"
+                Some "System.Collections.Generic"
+                Some "System"
+                Some "System.Console"
+            ]
+        this.TestF1Keywords(keywords, file)
+
+    [<Test>]
+    member public this.``Namespaces.AfterDot`` () =
+        let file =
+            [   "open $System.$Net"
+                "open $System.IO"
+                "open $System.$Collections.$Generic"
+                "open Microsoft.FSharp.Core"
+                ""    
+                "$System.$Console.$WriteLine()"
+            ]     
+        let keywords =
+            [   Some "System"
+                Some "System.Net"                
+                Some "System"
+                Some "System"
+                Some "System.Collections"
+                Some "System.Collections.Generic"
+                Some "System"
+                Some "System.Console"
+                Some "System.Console.WriteLine"
+            ]
+        this.TestF1Keywords(keywords, file)
+    
+    [<Test>]
+    member public this.``QuotedIdentifiers``() = 
+        let file = 
+            [
+                "let `$`escaped func`` x y = x + y"
+                "let ``escaped value`$` = 1"
+                "let x = 1"
+                "``escaped func`` x$ ``escaped value``"
+                "``escaped func``$ x ``escaped value``"
+                "``escaped func`` x $``escaped value``"
+                "let ``z$`` = 1"
+                "``$z`` |> printfn \"%d\""
+            ]
+        let keywords = 
+            [
+                Some "File1.escaped func"
+                Some "File1.escaped value"
+                Some "File1.x"
+                Some "File1.escaped func"
+                Some "File1.escaped value"
+                Some "File1.z"
+                Some "File1.z"
+            ]
+        this.TestF1Keywords(keywords, file)        
+
+    [<Test>]
+    member public this.``Attributes`` () = 
+        let file = 
+            [
+                "open System.Runtime.InteropServices"
+                "open System.Runtime.CompilerServices"
+                "[<St$ruct>]"
+                "type X = "
+                "    [<Default$Value(false)>]"
+                "    val mutable f : int"
+                "    [<Me$thodImpl(1s)>]"
+                "    member this.Run() = ()"
+                "[<StructLayout(LayoutKind.Auto, S$ize=1)>]"
+                "type Y = class end"
+            ]
+        let keywords = 
+            [
+                Some "Microsoft.FSharp.Core.StructAttribute.#ctor"
+                Some "Microsoft.FSharp.Core.DefaultValueAttribute.#ctor"
+                Some "System.Runtime.CompilerServices.MethodImplAttribute.#ctor"
+                Some "System.Runtime.InteropServices.StructLayoutAttribute.Size"
+            ]
+        this.TestF1Keywords(keywords, file)
+
+
+    [<Test>]
+    [<Category("TypeProvider")>]
+    [<Category("TypeProvider.StaticParameters")>]
+    //This test case Verify that when F1 is Hit on TypeProvider namespaces it contain the right keyword 
+    member public this.``TypeProvider.Namespaces`` () =
+        let file =
+            [   
+                "open N$1"
+            ]
+        let keywords =
+            [  
+                Some "N1"
+            ]
+        this.TestF1Keywords(keywords, file, 
+            addtlRefAssy = [System.IO.Path.Combine(System.Environment.CurrentDirectory,@"UnitTestsResources\MockTypeProviders\DummyProviderForLanguageServiceTesting.dll")])
+
+    [<Test>]
+    [<Category("TypeProvider")>]
+    [<Category("TypeProvider.StaticParameters")>]
+    //This test case Verify that when F1 is Hit on TypeProvider Type it contain the right keyword 
+    member public this.``TypeProvider.type`` () =
+       
+        let file =
+            [   
+                //Dummy Type Provider exposes a parametric type (N1.T) that takes 2 static params (string * int)
+                """let foo = typeof<N1.$T< const "Hello World",2>>"""
+            ]
+        let keywords =
+            [  
+                Some "N1.T"
+            ]
+        this.TestF1Keywords(keywords, file, 
+            addtlRefAssy = [System.IO.Path.Combine(System.Environment.CurrentDirectory,@"UnitTestsResources\MockTypeProviders\DummyProviderForLanguageServiceTesting.dll")])
+
+
+    [<Test>]
+    member public this.``EndOfLine``() =
+        let file =
+            [   "open System.Net$"
+                "open System.IO$"
+            ]
+        let keywords =
+            [   Some "System.Net"
+                Some "System.IO"
+            ]
+        this.TestF1Keywords(keywords, file)
+
+    [<Test>]
+    member public this.``EndOfLine2``() =
+        let file =
+            [   "module M"
+                "open System.Net$"
+                "open System.IO$"
+            ]
+        let keywords =
+            [   Some "System.Net"
+                Some "System.IO"
+            ]
+        this.TestF1Keywords(keywords, file)
+
+     
+    [<Test>]
+    member public this.``Comments``() =
+        let file =
+            [   "($* co$mment *$)"
+                "/$/ com$ment"
+            ]
+        let keywords =
+            [ Some "comment_FS"; Some "comment_FS"; Some "comment_FS"; Some "comment_FS"; Some "comment_FS"; ]
+        this.TestF1Keywords(keywords, file)
+    
+    [<Test>]
+    member public this.``FSharpEntities`` () =
+        let file =
+            [   "let (KeyValu$e(k,v)) = null"
+                "let w : int lis$t = []"
+                "let b = w.IsEm$pty"
+                "let m : map<int,int> = Map.empty"
+                "m.A$dd(1,1)"
+                "let z = Li$st.r$ev w"
+                "let o = No$ne"
+                "let o1 = So$me 1"
+                "let c : System.IO.Str$eam = null"
+                "c.Async$Read(10)"
+                "let r = r$ef 0"
+                "r.conten$ts"
+            ]
+        let keywords =
+            [   Some "Microsoft.FSharp.Core.Operators.KeyValuePattern``2"
+                Some "Microsoft.FSharp.Collections.FSharpList`1"
+                Some "Microsoft.FSharp.Collections.FSharpList`1.IsEmpty"
+                Some "Microsoft.FSharp.Collections.FSharpMap`2.Add"
+                Some "Microsoft.FSharp.Collections.ListModule"
+                Some "Microsoft.FSharp.Collections.ListModule.Reverse``1" // per F1 keyword spec - one tick for classes, two ticks for members 
+                Some "Microsoft.FSharp.Core.FSharpOption`1.None"
+                Some "Microsoft.FSharp.Core.FSharpOption`1.Some"
+                Some "System.IO.Stream" 
+                Some "Microsoft.FSharp.Control.CommonExtensions.AsyncReadBytes"
+                Some "Microsoft.FSharp.Core.Operators.Ref``1"
+                Some "Microsoft.FSharp.Core.FSharpRef`1.contents"
+            ]
+        this.TestF1Keywords(keywords, file)
+        
+    [<Test>]
+    member public this.``Keywords`` () =
+        let file =
+            [   "l$et r = ref 0"
+                "r :$= 1"
+                "let mut$able foo = 1"
+                "foo <$- 2"
+                "let$ z = 1"
+            ]
+        let keywords =
+            [   Some "let_FS"
+                Some ":=_FS"
+                Some "mutable_FS"
+                Some "<-_FS"
+                Some "let_FS"
+            ]
+        this.TestF1Keywords(keywords, file)
+
+    [<Test>]
+    member public this.``Regression.NewInstance.854367`` () =
+        let file =
+            [   "let q1 = new System.Runtime.Remoting.Type$Entry()"
+            ]
+        let keywords = 
+            [   Some "System.Runtime.Remoting.TypeEntry"
+            ]
+        this.TestF1Keywords(keywords, file)
+
+
+    [<Test>]
+    member public this.``Classes`` () =
+        let file =
+            [   "let q : System.Runtime.Remoting.TypeE$ntry = null"
+                "let q1 = new System.Runtime.Remoting.Type$Entry()"
+                "let w : System.Net.Web$Client = new System.Net.Web$Client()"
+                "let x : System.Collections.Generic.L$ist<int> = null"
+                "let z : Resi$zeArray<int> = null" 
+             ]
+        let keywords = 
+            [   Some "System.Runtime.Remoting.TypeEntry"
+                Some "System.Runtime.Remoting.TypeEntry"
+                Some "System.Net.WebClient"
+                Some "System.Net.WebClient.#ctor"
+                Some "System.Collections.Generic.List`1"
+                Some "System.Collections.Generic.List`1"
+             ]
+        this.TestF1Keywords(keywords, file)
+
+    [<Test>]
+    member public this.``Members`` () =        
+        let file =
+            [ "open System.Linq"
+              "open System"
+              "let l = new ResizeArray<int>()"
+              "let i = l.Cou$nt"
+              "l.Ad$d(1)"
+              "let m = new System.IO.MemoryStream()"
+              "m.BeginRe$ad()"
+              "l.Se$lect(fun i -> i + 1)"
+              "let d = new System.DateTi$me()"
+              "let s = String.Empty"
+              "s.Equ$als(null)"
+              "let i = 12"
+              "i.ToStr$ing()"
+            ]
+        let keywords = 
+            [ Some "System.Collections.Generic.List`1.Count"
+              Some "System.Collections.Generic.List`1.Add"
+              Some "System.IO.Stream.BeginRead"
+              Some "System.Linq.Enumerable.Select``2" // per F1 keyword spec - one tick for classes, two ticks for members 
+              Some "System.DateTime.#ctor"
+              Some "System.String.Equals"
+              Some "System.Int32.ToString"
+            ]
+        this.TestF1Keywords(keywords, file)
+
+// Allow the F1KeywordTests run under different context
+namespace UnitTests.Tests.LanguageService.F1Keyword
+open UnitTests.Tests.LanguageService
+open UnitTests.TestLib.LanguageService
+open UnitTests.TestLib.ProjectSystem
+open NUnit.Framework
+open Salsa.Salsa
+
+// context msbuild
+[<TestFixture>] 
+[<Category("LanguageService.MSBuild")>]
+type ``MSBuild`` = 
+   inherit F1KeywordTests
+   new() = { inherit F1KeywordTests(VsOpts = fst (Models.MSBuild())); }
+
+// Context project system
+[<TestFixture>] 
+[<Category("LanguageService.ProjectSystem")>]
+type ``ProjectSystem`` = 
+    inherit F1KeywordTests
+    new() = { inherit F1KeywordTests(VsOpts = LanguageServiceExtension.ProjectSystem); } 
\ No newline at end of file
diff --git a/vsintegration/src/unittests/Tests.LanguageService.General.fs b/vsintegration/src/unittests/Tests.LanguageService.General.fs
new file mode 100644
index 0000000..7e26f53
--- /dev/null
+++ b/vsintegration/src/unittests/Tests.LanguageService.General.fs
@@ -0,0 +1,605 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+namespace UnitTests.Tests.LanguageService
+
+open NUnit.Framework
+open System
+open System.Reflection
+open System.Runtime.InteropServices
+open Microsoft.VisualStudio.FSharp.LanguageService
+open Microsoft.FSharp.Compiler.SourceCodeServices
+open Salsa.Salsa
+open Salsa
+
+[<TestFixture>] 
+type IdealSource() = 
+    [<Test>]
+    member public rb.MultipleSourceIsDirtyCallsChangeTimestamps() = 
+        let recolorizeWholeFile() = ()
+        let recolorizeLine (_line:int) = ()
+        let isClosed() = false
+        let source =Source.CreateDelegatingSource(recolorizeWholeFile, recolorizeLine, "dummy.fs", isClosed, VsMocks.VsFileChangeEx())
+        let originalChangeCount = source.ChangeCount
+        let originalDirtyTime = source.DirtyTime
+
+        source.RecordChangeToView()
+        let secondChangeCount = source.ChangeCount
+        let secondDirtyTime = source.DirtyTime
+        let lastTickCount =  System.Environment.TickCount
+            
+        Assert.AreEqual(originalChangeCount + 1, secondChangeCount)
+        Assert.AreNotEqual(secondDirtyTime, originalDirtyTime)
+            
+        // Here's the test. NeedsVisualRefresh is true now, we call RecordChangeToView() and it should cause a new changeCount and dirty time.
+        while System.Environment.TickCount = lastTickCount do 
+            System.Threading.Thread.Sleep 10 // Sleep a little to avoid grabbing the same 'Now'
+        source.RecordChangeToView()
+        let thirdChangeCount = source.ChangeCount
+        let thirdDirtyTime = source.DirtyTime
+            
+        Assert.AreEqual(secondChangeCount + 1, thirdChangeCount)
+        Assert.AreNotEqual(thirdDirtyTime, secondDirtyTime)            
+
+
+
+
+open System
+open System.IO
+open NUnit.Framework
+open Salsa.Salsa
+open Salsa.VsOpsUtils
+open UnitTests.TestLib.Salsa
+open UnitTests.TestLib.Utils
+open Microsoft.FSharp.Compiler
+open UnitTests.TestLib.LanguageService
+type GeneralTests() =
+    inherit LanguageServiceBaseTests()
+
+    let stopWatch = new System.Diagnostics.Stopwatch()
+    let ResetStopWatch() = stopWatch.Reset(); stopWatch.Start()
+    let time1 op a message = 
+        ResetStopWatch()
+        let result = op a
+        printf "%s %d ms\n" message stopWatch.ElapsedMilliseconds
+        result
+
+    let publicTypesInAsm(asmfile : string) =
+        printfn "Validating assembly '%s'" asmfile
+        let codeBase = (new Uri(Assembly.GetExecutingAssembly().CodeBase)).LocalPath |> Path.GetDirectoryName
+        let asm = Assembly.LoadFrom(Path.Combine(codeBase, asmfile))
+
+        // For public types that have ComVisible, validate that the constructor is internal
+        asm.GetTypes()
+        |> Seq.fold(fun n t ->
+                        if t.IsPublic then
+                            if Array.length (t.GetCustomAttributes(typeof<ComVisibleAttribute>, false)) > 0 then
+                                t.GetConstructors()
+                                |> Seq.fold(fun m c ->
+                                                if c.IsPublic then
+                                                    printfn "    Public type (ComVisible, public Constructor),%s" t.FullName
+                                                    m + 1
+                                                else m
+                                            ) n
+                            else
+                                printfn "    Type: %s" t.FullName
+                                n + 1
+                        else
+                            let CVAs = t.GetCustomAttributes(typeof<ComVisibleAttribute>, false)
+                            let CVAs = CVAs |> Array.map (fun o -> o :?> ComVisibleAttribute)
+                            for cva in CVAs do
+                                if cva.Value then
+                                    Assert.Fail(sprintf "Type %s is internal, but also ComVisible(true)" t.FullName)
+                            let CIAs = t.GetCustomAttributes(typeof<ClassInterfaceAttribute>, false)
+                            let CIAs = CIAs |> Array.map (fun o -> o :?> ClassInterfaceAttribute)
+                            for cia in CIAs do
+                                if cia.Value <> ClassInterfaceType.None then
+                                    Assert.Fail(sprintf "Type %s is internal, but also ClassInterface(<something-other-than-none>)" t.FullName)
+                            n
+                   ) 0
+
+    [<Test>]
+    member public this.``PendingRequests``() =
+        let makeRequest (reason : BackgroundRequestReason) = new BackgroundRequest(false, Reason = reason)
+
+        let requests = Microsoft.VisualStudio.FSharp.LanguageService.PendingRequests()
+        
+        let verify r = 
+            let dequeued = requests.Dequeue()
+            Assert.AreEqual(r, dequeued.Reason)
+
+        // Ui1 + Ui2 = Ui2
+        // should have only last
+        requests.Enqueue(makeRequest BackgroundRequestReason.MemberSelect)
+        requests.Enqueue(makeRequest BackgroundRequestReason.Goto)
+        verify BackgroundRequestReason.Goto
+        Assert.AreEqual(0, requests.Count)
+
+        // n-Ui1 + Ui2 = Ui2
+        // should have only last
+        requests.Enqueue(makeRequest BackgroundRequestReason.FullTypeCheck)
+        requests.Enqueue(makeRequest BackgroundRequestReason.MemberSelect)
+        verify BackgroundRequestReason.MemberSelect
+        Assert.AreEqual(0, requests.Count)
+
+        // n-Ui1 + n-Ui2 = n-Ui2
+        requests.Enqueue(makeRequest BackgroundRequestReason.FullTypeCheck)
+        requests.Enqueue(makeRequest BackgroundRequestReason.UntypedParse)
+        verify BackgroundRequestReason.UntypedParse
+        Assert.AreEqual(0, requests.Count)
+
+        // Ui1 + n-Ui2 = Ui1 + n-Ui2
+        requests.Enqueue(makeRequest BackgroundRequestReason.MemberSelect)
+        requests.Enqueue(makeRequest BackgroundRequestReason.UntypedParse)
+        verify BackgroundRequestReason.MemberSelect
+        Assert.AreEqual(1, requests.Count)
+        verify BackgroundRequestReason.UntypedParse
+        Assert.AreEqual(0, requests.Count)
+
+        // (Ui1 + n-Ui2) + Ui3 = Ui3
+        requests.Enqueue(makeRequest BackgroundRequestReason.MemberSelect)
+        requests.Enqueue(makeRequest BackgroundRequestReason.UntypedParse)
+        requests.Enqueue(makeRequest BackgroundRequestReason.MemberSelect)
+        verify BackgroundRequestReason.MemberSelect
+        Assert.AreEqual(0, requests.Count)
+
+        // (Ui1 + n-Ui2) + n-Ui3 = Ui1 + n-Ui3
+        requests.Enqueue(makeRequest BackgroundRequestReason.MemberSelect)
+        requests.Enqueue(makeRequest BackgroundRequestReason.UntypedParse)
+        requests.Enqueue(makeRequest BackgroundRequestReason.FullTypeCheck)
+        verify BackgroundRequestReason.MemberSelect
+        Assert.AreEqual(1, requests.Count)
+        verify BackgroundRequestReason.FullTypeCheck
+        Assert.AreEqual(0, requests.Count)
+        
+
+    [<Test>]
+    member public this.``PublicSurfaceArea.DotNetReflection``() =
+        let ps = publicTypesInAsm @"fsharp.projectsystem.fsharp.dll"
+        Assert.AreEqual(3, ps)  // TPTOP(x2) stuff and BuildPropertyDescriptor
+        let ls = publicTypesInAsm @"fsharp.languageservice.dll"
+        Assert.AreEqual(0, ls)
+        let comp = publicTypesInAsm @"fsharp.compiler.dll"
+        Assert.AreEqual(0, comp)
+        let compis = publicTypesInAsm @"FSharp.Compiler.Interactive.Settings.dll"
+        Assert.AreEqual(5, compis)
+        let compserver = publicTypesInAsm @"FSharp.Compiler.Server.Shared.dll"
+        Assert.AreEqual(0, compserver)
+        let lsbase = publicTypesInAsm @"FSharp.LanguageService.Base.dll"
+        Assert.AreEqual(0, lsbase)
+        let psbase = publicTypesInAsm @"FSharp.ProjectSystem.Base.dll"
+        Assert.AreEqual(14, psbase)
+        let fsi = publicTypesInAsm @"FSharp.VS.FSI.dll"
+        Assert.AreEqual(1, fsi)
+
+    [<Test>]
+    member public this.``PublicSurfaceArea.DotNetReflectionAndTypeProviders``() =
+        let tp = publicTypesInAsm @"FSharp.Data.TypeProviders.dll"
+        Assert.AreEqual(1, tp)  // the 'DataProviders' type that is decorated with [<TypeProvider>] must be public\
+        let curDir = (new Uri(Assembly.GetExecutingAssembly().CodeBase)).LocalPath |> Path.GetDirectoryName
+        let script = """
+open Microsoft.FSharp.Core.CompilerServices
+
+let cfg = new TypeProviderConfig(fun _ -> true)
+cfg.IsInvalidationSupported <- false
+cfg.IsHostedExecution <- false
+cfg.ReferencedAssemblies <- Array.create 0 ""
+cfg.ResolutionFolder <- @"c:\"
+cfg.RuntimeAssembly <- ""
+cfg.TemporaryFolder <- ""
+ 
+let tp = new Microsoft.FSharp.Data.TypeProviders.DesignTime.DataProviders(cfg)
+let ipn = tp :> IProvidedNamespace
+let itp = tp :> ITypeProvider
+
+let types = 
+    [   "ODataService"
+        "WsdlService"
+        "SqlDataConnection"
+        "SqlEntityConnection"
+        "DbmlFile"
+        "EdmxFile"
+        ]
+
+for p in types do
+    printfn "%s" p
+    let pType = ipn.ResolveTypeName(p)
+    let odataStaticArgs = itp.GetStaticParameters(pType)
+    for sa in odataStaticArgs do
+        printfn "    %s:%s" sa.Name sa.ParameterType.Name
+        """
+        let expected = """ODataService
+    ServiceUri:String
+    LocalSchemaFile:String
+    ForceUpdate:Boolean
+    ResolutionFolder:String
+    DataServiceCollection:Boolean
+WsdlService
+    ServiceUri:String
+    LocalSchemaFile:String
+    ForceUpdate:Boolean
+    ResolutionFolder:String
+    MessageContract:Boolean
+    EnableDataBinding:Boolean
+    Serializable:Boolean
+    Async:Boolean
+    CollectionType:String
+SqlDataConnection
+    ConnectionString:String
+    ConnectionStringName:String
+    LocalSchemaFile:String
+    ForceUpdate:Boolean
+    Pluralize:Boolean
+    Views:Boolean
+    Functions:Boolean
+    ConfigFile:String
+    DataDirectory:String
+    ResolutionFolder:String
+    StoredProcedures:Boolean
+    Timeout:Int32
+    ContextTypeName:String
+    Serializable:Boolean
+SqlEntityConnection
+    ConnectionString:String
+    ConnectionStringName:String
+    LocalSchemaFile:String
+    Provider:String
+    EntityContainer:String
+    ConfigFile:String
+    DataDirectory:String
+    ResolutionFolder:String
+    ForceUpdate:Boolean
+    Pluralize:Boolean
+    SuppressForeignKeyProperties:Boolean
+DbmlFile
+    File:String
+    ResolutionFolder:String
+    ContextTypeName:String
+    Serializable:Boolean
+EdmxFile
+    File:String
+    ResolutionFolder:String
+"""
+        File.WriteAllText(Path.Combine(curDir, "tmp.fsx"), script)
+        let psi = System.Diagnostics.ProcessStartInfo("fsi.exe", "-r:FSharp.Data.TypeProviders.dll tmp.fsx")
+        psi.WorkingDirectory <- curDir
+        psi.RedirectStandardOutput <- true
+        psi.UseShellExecute <- false
+        let p = System.Diagnostics.Process.Start(psi)
+        let out = p.StandardOutput.ReadToEnd()
+        p.WaitForExit()
+        let out = out.Replace("\r\n", "\n")
+        let expected = expected.Replace("\r\n", "\n")
+        Assert.AreEqual(expected, out)
+
+    [<Test>]
+    member public this.``ReconcileErrors.Test1``() = 
+        let (_solution, project, file) = this.CreateSingleFileProject(["erroneous"])
+        Build project |> ignore
+        TakeCoffeeBreak(this.VS)  // Error list is populated on idle
+        ()
+ 
+    /// FEATURE: (Project System only) Adding a file outside the project directory creates a link
+    [<Test>]
+    [<Category("PerfCheck")>]
+    member public this.``ProjectSystem.FilesOutsideProjectDirectoryBecomeLinkedFiles``() =
+        use _guard = this.UsingNewVS()
+        if OutOfConeFilesAreAddedAsLinks(this.VS) then
+            let solution = this.CreateSolution()
+            let project = CreateProject(solution,"testproject")
+            let file1 = AddFileFromTextEx(project, @"..\LINK.FS", @"..\link.fs", BuildAction.Compile,
+                                        ["#light"
+                                         "type Bob() = "
+                                         "    let x = 1"])
+            let file1 = OpenFile(project, @"..\link.fs")
+            Save(project)
+            let projFileText = System.IO.File.ReadAllText(ProjectFile(project))
+            AssertMatchesRegex '<' @"<ItemGroup>\s*<Compile Include=""..\\link.fs"">\s*<Link>link.fs</Link>" projFileText
+                                  
+    [<Test>]
+    [<Category("PerfCheck")>]
+    member public this.``Lexer.CommentsLexing.Bug1548``() =
+        let scan = new FSharpScanner(fun source -> 
+                        let filename = "test.fs"
+                        let defines = [ "COMPILED"; "EDITING" ]
+            
+                        SourceTokenizer(defines,filename).CreateLineTokenizer(source))
+        
+        let cm = Microsoft.VisualStudio.FSharp.LanguageService.TokenColor.Comment
+        let kw = Microsoft.VisualStudio.FSharp.LanguageService.TokenColor.Keyword
+        
+        // This specifies the source code to test and a collection of tokens that 
+        // we want to find in the result (note: it doesn't have to contain every token, because 
+        // behavior for some of them is undefined - e.g. "(* "\"*)" - what is token here?
+        let sources = 
+          [ "// some comment", 
+                [ (0, 1), cm; (2, 2), cm; (3, 6), cm; (7, 7), cm; (8, 14), cm ]
+            "// (* hello // 12345\nlet",
+                [ (6, 10), cm; (15, 19), cm; (0, 2), kw  ] // checks 'hello', '12345' and keyword 'let'
+            "//- test",
+                [ (0, 2), cm; (4, 7), cm ] // checks whether '//-' isn't treated as an operator
+
+            /// same thing for XML comments - these are treated in a different lexer branch
+            "/// some comment", 
+                [ (0, 2), cm; (3, 3), cm; (4, 7), cm; (8, 8), cm; (9, 15), cm ]
+            "/// (* hello // 12345\nmember",
+                [ (7, 11), cm; (16, 20), cm; (0, 5), kw  ] 
+            "///- test",
+                [ (0, 3), cm; (5, 8), cm ]
+            
+            //// same thing for "////" - these are treated in a different lexer branch
+            "//// some comment", 
+                [ (0, 3), cm; (4, 4), cm; (5, 8), cm; (9, 9), cm; (10, 16), cm ]
+            "//// (* hello // 12345\nlet",
+                [ (8, 12), cm; (17, 21), cm; (0, 2), kw  ] 
+            "////- test",
+                [ (0, 4), cm; (6, 9), cm ]
+                
+            "(* test 123 (* 456 nested *) comments *)",
+                [ (3, 6), cm; (8, 10), cm; (15, 17), cm; (19, 24), cm; (29, 36), cm ] // checks 'test', '123', '456', 'nested', 'comments'
+            "(* \"with 123 \\\" *)\" string *)",    
+                [ (4, 7), cm; (9, 11), cm; (20, 25), cm ]  // checks 'with', '123', 'string'
+            "(* @\"with 123 \"\" *)\" string *)",
+                [ (5, 8), cm; (10, 12), cm; (21, 26), cm ]  // checks 'with', '123', 'string'
+          ]
+                        
+        for lineText, expected in sources do
+            scan.SetLineText lineText
+            
+            let currentTokenInfo = new Microsoft.VisualStudio.FSharp.LanguageService.TokenInfo()
+            let lastColorState = 0 // First line of code, so no previous state
+            currentTokenInfo.EndIndex <- -1
+            let refState = ref (ColorStateLookup.LexStateOfColorState lastColorState)
+            
+            // Lex the line and add all lexed tokens to a dictionary
+            let lexed = new System.Collections.Generic.Dictionary<_, _>()
+            while scan.ScanTokenAndProvideInfoAboutIt(1, currentTokenInfo, refState) do
+                lexed.Add( (currentTokenInfo.StartIndex, currentTokenInfo.EndIndex), currentTokenInfo.Color )
+                
+            // Verify that all tokens in the specified list occur in the lexed result
+            for pos, clr in expected do
+                let (succ, v) = lexed.TryGetValue(pos)
+                let found = lexed |> Seq.map (fun kvp -> kvp.Key, kvp.Value) |> Seq.toList 
+                AssertEqualWithMessage(true, succ, sprintf "Cannot find token %A at %A in %A\nFound: %A" clr pos lineText found)
+                AssertEqualWithMessage(clr, v, sprintf "Wrong color of token %A at %A in %A\nFound: %A" clr pos lineText found)
+           
+        
+    // This was a bug in ReplaceAllText (subsequent calls to SetMarker would fail)
+    [<Test>]
+    member public this.``Salsa.ReplaceAllText``() =
+        let code = 
+                ["#light"; 
+                 "let x = \"A String Literal\""]
+        let (_solution, _project, file) = this.CreateSingleFileProject(code)
+        
+        // Sanity check
+        MoveCursorToStartOfMarker(file,"#light")
+        AssertEqual(TokenType.PreprocessorKeyword, GetTokenTypeAtCursor(file))
+        MoveCursorToEndOfMarker(file,"let x = ")
+        AssertEqual(TokenType.String, GetTokenTypeAtCursor(file))
+        
+        // Replace file contents
+        ReplaceFileInMemory file
+                            ["#light";
+                              "let x = 42 // comment!";
+                              "let y = \"A String Literal\""]
+        
+        // Verify able to move cursor and get correct results
+        MoveCursorToEndOfMarker(file, "comment")
+        AssertEqual(TokenType.Comment, GetTokenTypeAtCursor(file))   // Not a string, as was origionally
+        MoveCursorToEndOfMarker(file, "let y = ")
+        AssertEqual(TokenType.String, GetTokenTypeAtCursor(file))   // Able to find new marker
+        MoveCursorToStartOfMarker(file, "let y = ")
+        AssertEqual(TokenType.Keyword, GetTokenTypeAtCursor(file))  // Check MoveCursorToStartOfMarker
+        
+    
+
+    // Make sure that possible overloads (and other related errors) are shown in the error list
+    [<Test>]
+    [<Category("PerfCheck")>]
+    member public this.``ErrorLogging.Bug5144``() =
+        use _guard = this.UsingNewVS()
+        let solution = this.CreateSolution()
+        let project = CreateProject(solution,"testproject")
+        let fs1 = AddFileFromText(project,"File1.fs",
+                                      ["namespace N"
+                                       "module M = "
+                                       "    type LineChart() ="
+                                       "        member x.Plot(f : float->float, xmin:float, xmax:float) = ()"
+                                       "        member x.Plot(f : System.Func<double, double>, xmin:float, xmax:float) = ()"
+                                      ])
+        let fs2 = AddFileFromText(project,"File2.fs",
+                                      ["let p = new N.M.LineChart()"
+                                       "p.Plot(sin, 0., 0.)"])
+        let build = time1 Build project "Time to build project"
+        
+        Assert.IsTrue(not build.BuildSucceeded, "Expected build to fail")              
+        
+        if SupportsOutputWindowPane(this.VS) then 
+            Helper.AssertListContainsInOrder(GetOutputWindowPaneLines(this.VS), 
+                                      ["error FS0041: A unique overload for method 'Plot' could not be determined based on type information prior to this program point. A type annotation may be needed. Candidates: member N.M.LineChart.Plot : f:(float -> float) * xmin:float * xmax:float -> unit, member N.M.LineChart.Plot : f:System.Func<double,double> * xmin:float * xmax:float -> unit"])
+
+    [<Category("TakesMoreThanFifteenSeconds")>]
+    [<Test>]
+    member public this.``ExhaustivelyScrutinize.ThisOnceAsserted``() =     
+        Helper.ExhaustivelyScrutinize(
+          this.TestRunner,
+          [ """let F() =                 """
+            """    if true then [],      """
+            """    elif true then [],""  """
+            """    else [],""            """ ]
+            )
+
+    [<Category("TakesMoreThanFifteenSeconds")>]
+    [<Test>]
+    member public this.``ExhaustivelyScrutinize.ThisOnceAssertedToo``() =     
+        Helper.ExhaustivelyScrutinize(
+            this.TestRunner,
+            [ "type C() = "
+              "    member this.F() = ()"
+              "    interface System.IComparable with "
+              "        member __.CompareTo(v:obj) = 1" ]
+            )
+    [<Category("TakesMoreThanFifteenSeconds")>]
+    [<Test>]
+    member public this.``ExhaustivelyScrutinize.ThisOnceAssertedThree``() =     
+        Helper.ExhaustivelyScrutinize(
+            this.TestRunner,
+            [ "type Foo =" 
+              "    { mutable Data: string }"
+              "    member x.XmlDocSig "
+              "        with get() = x.Data"
+              "        and set(v) = x.Data <- v" ]
+              )
+    [<Test>]
+    member public this.``ExhaustivelyScrutinize.ThisOnceAssertedFour``() =     
+        Helper.ExhaustivelyScrutinize(
+            this.TestRunner,
+            [ "let y=new"
+              "let z=4" ]
+              )
+
+    [<Test>]
+    member public this.``ExhaustivelyScrutinize.ThisOnceAssertedFive``() =     
+        Helper.ExhaustivelyScrutinize(this.TestRunner, [ """CSV.File<@"File1.txt">.[0].""" ])  // <@ is one token, wanted < @"...
+
+    [<Category("TakesMoreThanFifteenSeconds")>]
+    [<Test>]
+    member public this.``ExhaustivelyScrutinize.Bug2277``() =     
+        Helper.ExhaustivelyScrutinize(
+            this.TestRunner,
+              ["#light"
+               "open Microsoft.FSharp.Plot.Excel"
+               "open Microsoft.FSharp.Plot.Interactive"
+               "let ps = [| (1.,\"c\"); (-2.,\"p\") |]"
+               "plot (Bars(ps))"
+               "let xs = [| 1.0 .. 20.0 |]"
+               "let ys = [| 2.0 .. 21.0 |]"
+               "let pp= plot(Area(xs,ys))" ]
+                )
+                                     
+    [<Category("TakesMoreThanFifteenSeconds")>]
+    [<Test>]
+    member public this.``ExhaustivelyScrutinize.Bug2283``() =     
+        Helper.ExhaustivelyScrutinize(
+            this.TestRunner,
+              ["#light"
+               "#r \"NestedClasses.dll\"" // Scenario requires this assembly not exist.
+               "//753 atomType -> atomType DOT path typeArgs"
+               "let specificIdent (x : RootNamespace.ClassOfT<int>.NestedClassOfU<string>) = x"
+               "let x = new RootNamespace.ClassOfT<int>.NestedClassOfU<string>()"
+               "if specificIdent x <> x then exit 1"
+               "exit 0"] 
+                )
+
+
+   /// Verifies that token info returns correct trigger classes 
+    /// - this is used in MPF for triggering various intellisense features
+    [<Test>]
+    member public this.``TokenInfo.TriggerClasses``() =      
+      let important = 
+        [ // Member select for dot completions
+          Parser.DOT, (TokenColorKind.Operator,TokenCharKind.Delimiter,TriggerClass.MemberSelect)
+          // for parameter info
+          Parser.LPAREN, (TokenColorKind.Text,TokenCharKind.Delimiter, TriggerClass.ParamStart ||| TriggerClass.MatchBraces)
+          Parser.COMMA,  (TokenColorKind.Text,TokenCharKind.Delimiter, TriggerClass.ParamNext)
+          Parser.RPAREN, (TokenColorKind.Text,TokenCharKind.Delimiter, TriggerClass.ParamEnd ||| TriggerClass.MatchBraces) ]
+      let matching =           
+        [ // Other cases where we expect MatchBraces
+          Parser.LQUOTE("", false); Parser.LBRACK; Parser.LBRACE; Parser.LBRACK_BAR;
+          Parser.RQUOTE("", false); Parser.RBRACK; Parser.RBRACE; Parser.BAR_RBRACK ]
+        |> List.map (fun n -> n, (TokenColorKind.Text,TokenCharKind.Delimiter, TriggerClass.MatchBraces))
+      for tok, expected in List.concat [ important; matching ] do
+        let info = TestExpose.TokenInfo tok
+        AssertEqual(expected, info)
+
+    [<Test>]
+    member public this.``MatchingBraces.VerifyMatches``() = 
+        let content = 
+            [|
+            "
+                let x = (1, 2)//1
+                let y =    (  3 + 1  ) * 2
+                let z =
+                   async {
+                       return 10
+                   }
+                let lst = 
+                    [// list_start
+                        1;2;3
+                    ]//list_end
+                let arr = 
+                    [|
+                        1
+                        2
+                    |]
+                let quote = <@(* S0 *) 1 @>(* E0 *)
+                let quoteWithNestedList = <@(* S1 *) ['x';'y';'z'](* E_L*) @>(* E1 *)
+                [< System.Serializable() >]
+                type T = class end
+            "
+            |]
+        let (_solution, _project, file) =  this.CreateSingleFileProject(String.concat Environment.NewLine content)
+
+        let getPos marker = 
+            // fix 1-based positions to 0-based
+            MoveCursorToStartOfMarker(file, marker)
+            let (row, col) = GetCursorLocation(file)
+            (row - 1), (col - 1)
+
+        let setPos row col = 
+            // fix 0-based positions to 1-based
+            MoveCursorTo(file, row + 1, col + 1)            
+
+        let checkBraces startMarker endMarker expectedSpanLen = 
+            let (startRow, startCol) = getPos startMarker
+            let (endRow, endCol) = getPos endMarker
+
+            let checkTextSpan (actual : TextSpan) expectedRow expectedCol = 
+                Assert.IsTrue(actual.iStartLine = actual.iEndLine, "Start and end of the span should be on the same line")
+                Assert.AreEqual(expectedRow, actual.iStartLine, "Unexpected row")
+                Assert.AreEqual(expectedCol, actual.iStartIndex, "Unexpected column")
+                Assert.IsTrue(actual.iEndIndex = (actual.iStartIndex + expectedSpanLen), sprintf "Span should have length == %d" expectedSpanLen)
+
+            let checkBracesForPosition row col = 
+                setPos row col
+                let braces = GetMatchingBracesForPositionAtCursor(file)
+                Assert.AreEqual(1, braces.Length, "One result expected")
+
+                let (lbrace, rbrace) = braces.[0]
+                checkTextSpan lbrace startRow startCol
+                checkTextSpan rbrace endRow endCol
+
+            checkBracesForPosition startRow startCol
+            checkBracesForPosition endRow endCol           
+            
+        checkBraces "(1" ")//1" 1
+        checkBraces "( " ") *" 1
+        checkBraces "{" "}" 1
+        checkBraces "[// list_start" "]//list_end" 1
+        checkBraces "[|" "|]" 2
+        checkBraces "<@(* S0 *)" "@>(* E0 *)" 2
+        checkBraces "<@(* S1 *)" "@>(* E1 *)" 2
+        checkBraces "['x'" "](* E_L*)" 1
+        checkBraces "[<" ">]" 2
+
+//Allow the TimeStampTests run under different context
+namespace UnitTests.Tests.LanguageService.General
+open UnitTests.Tests.LanguageService
+open UnitTests.TestLib.LanguageService
+open UnitTests.TestLib.ProjectSystem
+open NUnit.Framework
+open Salsa.Salsa
+
+// context msbuild
+[<TestFixture>]
+[<Category("LanguageService.MSBuild")>]
+type ``MSBuild`` = 
+   inherit GeneralTests
+   new() = { inherit GeneralTests(VsOpts = fst (Models.MSBuild())); }
+
+// Context project system
+[<TestFixture>]
+[<Category("LanguageService.ProjectSystem")>]
+type ``ProjectSystem`` = 
+    inherit GeneralTests
+    new() = { inherit GeneralTests(VsOpts = LanguageServiceExtension.ProjectSystem); } 
\ No newline at end of file
diff --git a/vsintegration/src/unittests/Tests.LanguageService.GotoDefinition.fs b/vsintegration/src/unittests/Tests.LanguageService.GotoDefinition.fs
new file mode 100644
index 0000000..b61acb5
--- /dev/null
+++ b/vsintegration/src/unittests/Tests.LanguageService.GotoDefinition.fs
@@ -0,0 +1,1457 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+namespace UnitTests.Tests.LanguageService
+
+open System
+open System.IO
+open NUnit.Framework
+open Salsa.Salsa
+open Salsa.VsOpsUtils
+open UnitTests.TestLib.Salsa
+open UnitTests.TestLib.Utils
+open System.Collections.Generic
+open System.Text.RegularExpressions
+open UnitTests.TestLib.LanguageService
+
+type GotoDefinitionTests()  = 
+    inherit LanguageServiceBaseTests()
+
+    //GoToDefinitionSuccess Helper Function
+    member private this.VerifyGoToDefnSuccessAtStartOfMarker(fileContents : string, marker : string,  definitionCode : string,?addtlRefAssy : list<string>) =
+        let (sln, proj, file) = this.CreateSingleFileProject(fileContents, ?references = addtlRefAssy)
+
+        MoveCursorToStartOfMarker (file, marker)
+        let identifier = (GetIdentifierAtCursor file).Value |> fst //use marker to get the identifier
+        let result = GotoDefinitionAtCursor file
+        CheckGotoDefnResult
+            (GotoDefnSuccess identifier definitionCode) 
+            file
+            result 
+    
+    member private this.VerifyGotoDefnSuccessForNonIdentifierAtStartOfMarker(fileContents : string, marker: string, pos : int * int, ?extraRefs) =
+        let (_, _, file) = this.CreateSingleFileProject(fileContents, ?references = extraRefs)
+        MoveCursorToStartOfMarker (file, marker)
+        let result = GotoDefinitionAtCursor file
+        Assert.IsTrue(result.Success)
+        let actualPos = (result.Span.iStartLine, result.Span.iStartIndex)
+        let line = GetLineNumber file (result.Span.iStartLine + 1)
+        printfn "Actual line:%s, actual pos:%A" line actualPos
+        Assert.AreEqual(pos, actualPos)
+                    
+    //GoToDefinitionFail Helper Function
+    member private this.VerifyGoToDefnFailAtStartOfMarker(fileContents : string,  marker :string,?addtlRefAssy : list<string>) =
+        
+        this.VerifyGoToDefnFailAtStartOfMarker(
+            fileContents = fileContents,
+            marker = marker,
+            f = (fun (file,result) -> CheckGotoDefnResult GotoDefnFailure file result),
+            ?addtlRefAssy = addtlRefAssy
+            )
+
+
+    //GoToDefinitionFail Helper Function
+    member private this.VerifyGoToDefnFailAtStartOfMarker(fileContents : string,  marker :string, f : OpenFile * GotoDefnResult -> unit, ?addtlRefAssy : list<string>) =
+        let (sln, proj, file) = this.CreateSingleFileProject(fileContents, ?references = addtlRefAssy)
+
+        MoveCursorToStartOfMarker (file, marker)
+        let result = GotoDefinitionAtCursor file
+        f (file, result)
+
+
+    //GoToDefinition verify no Error dialog
+    //The verification result should be:
+    //  Fail at automation lab
+    //  Succeed on dev machine with enlistment installed.
+    member private this.VerifyGoToDefnNoErrorDialogAtStartOfMarker(fileContents : string,  marker :string, definitionCode : string, ?addtlRefAssy : list<string>) =
+        let (sln, proj, file) = this.CreateSingleFileProject(fileContents, ?references = addtlRefAssy)
+
+        MoveCursorToStartOfMarker (file, marker)
+        let identifier = (GetIdentifierAtCursor file).Value |> fst //use marker to get the identifier
+        let result = GotoDefinitionAtCursor file
+        if not result.Success then
+            CheckGotoDefnResult
+                GotoDefnFailure 
+                file
+                result
+        else
+            CheckGotoDefnResult
+                (GotoDefnSuccess identifier definitionCode) 
+                file 
+                result 
+    
+    [<Test>]                                  
+    member this.``Operators.TopLevel``() = 
+        this.VerifyGotoDefnSuccessForNonIdentifierAtStartOfMarker(
+            fileContents = """
+                let (===) a b = a = b
+                let _ = 1 === 2
+                """,
+            marker = "=== 2",
+            pos=(1,21)
+            )
+
+    [<Test>]                                  
+    member this.``Operators.Member``() = 
+        this.VerifyGotoDefnSuccessForNonIdentifierAtStartOfMarker(
+            fileContents = """
+                type U = U
+                    with
+                    static member (+++) (U, U) = U
+                let _ = U +++ U
+                """,
+            marker = "++ U",
+            pos=(3,35)
+            )
+
+    [<Test>]
+    member public this.``Value``() = 
+        this.VerifyGoToDefnSuccessAtStartOfMarker(
+            fileContents = """
+                type DiscUnion =
+                    | Alpha of string
+                    | Beta of decimal * unit
+                    | Gamma
+
+                let valueX = Beta(1.0M, ())(*GotoTypeDef*)
+                let valueY = valueX (*GotoValDef*)
+                """,
+            marker = "valueX (*GotoValDef*)",
+            definitionCode = "let valueX = Beta(1.0M, ())(*GotoTypeDef*)")
+    
+    [<Test>]
+    member public this.``DisUnionMember``() =
+        this.VerifyGoToDefnSuccessAtStartOfMarker(
+                            fileContents = """
+                type DiscUnion =
+                    | Alpha of string
+                    | Beta of decimal * unit
+                    | Gamma
+
+                let valueX = Beta(1.0M, ())(*GotoTypeDef*)
+                let valueY = valueX (*GotoValDef*)
+                """,
+            marker = "Beta(1.0M, ())(*GotoTypeDef*)",
+            definitionCode = "| Beta of decimal * unit")        
+
+    [<Test>]
+    member public this.``PrimitiveType``() =
+        this.VerifyGoToDefnFailAtStartOfMarker(
+            fileContents = """
+                // Can't goto def on an int literal
+                let bi = 123456I""",
+            marker = "123456I")
+           
+    [<Test>]
+    member public this.``OnTypeDefintion``() =
+        this.VerifyGoToDefnSuccessAtStartOfMarker(
+            fileContents = """
+                //regression test for bug 2516
+                type One (*Marker1*) = One
+                let f (x : One (*Marker2*)) = 2
+                """,
+            marker = "One (*Marker1*)",
+            definitionCode = "type One (*Marker1*) = One")
+
+    [<Test>]
+    member public this.``Parameter``() = 
+        this.VerifyGoToDefnSuccessAtStartOfMarker(
+            fileContents = """
+                //regression test for bug 2516
+                type One (*Marker1*) = One
+                let f (x : One (*Marker2*)) = 2
+                """,
+            marker = "One (*Marker2*)",
+            definitionCode = "type One (*Marker1*) = One")    
+
+    [<Test>]
+    [<Category("TypeProvider")>]
+    [<Category("TypeProvider.DefinitionLocationAttribute")>]
+    // This test case check the GotoDefinition (i.e. the TypeProviderDefinitionLocation Attribute)
+    // We expect the correct FilePath, Line and Column on provided: Type, Event, Method, and Property
+    // TODO: add a case for a provided Field
+    member public this.``GotoDefinition.TypeProvider.DefinitionLocationAttribute``() =
+        use _guard = this.UsingNewVS()
+        // Note that the verification helped method is custom because we *do* care about the column as well, 
+        // which is something that the general purpose method in this file (surprisingly!) does not do.
+        let VerifyGoToDefnSuccessAtStartOfMarkerColumn(fileContents : string, marker : string,  definitionCode : string, typeProviderAssembly : string, columnMarker : string) =
+            let (sln, proj, file) = GlobalFunctions.CreateNamedSingleFileProject (this.VS, (fileContents, "File.fs"))  
+
+            // Add reference to the type provider
+            this.AddAssemblyReference(proj,typeProviderAssembly)
+
+            // Identify (line,col) of the destination, i.e. where we expect to land after hitting F12
+            // We do this to avoid hardcoding absolute numbers in the code.
+            MoveCursorToStartOfMarker (file,columnMarker)
+            let _,column = GetCursorLocation(file)
+
+            // Put curson at start of marker and then hit F12
+            MoveCursorToStartOfMarker (file, marker)
+            let identifier = (GetIdentifierAtCursor file).Value |> fst
+            let result = GotoDefinitionAtCursor file
+
+            // Execute validation (on file name and line)                   
+            CheckGotoDefnResult
+                (GotoDefnSuccess identifier definitionCode) 
+                file 
+                result 
+            
+            // Reminder: coordinates in the F# compiler are 1-based for lines, and 0-based for columns
+            //           coordinates from type providers are 1-based for both lines and columns
+            //           GetCursorLocation() seems to return something even more off by 1...
+            let column' = column - 2
+
+            match result.ToOption() with 
+            | Some(span,_) -> Assert.AreEqual(column',span.iStartIndex, "The cursor landed on the incorrect column!") 
+            | None ->  Assert.Fail <| sprintf "Expected to find the definition at column '%d' but GotoDefn failed." column'
+
+        // Basic scenario on a provided Type
+        let ``Type.BasicScenario``() = 
+            VerifyGoToDefnSuccessAtStartOfMarkerColumn("""
+                let a = typeof<N.T(*GotoValDef*)>
+                // A0(*ColumnMarker*)1234567890
+                // B01234567890
+                // C01234567890 """,
+            "T(*GotoValDef*)",
+             "// A0(*ColumnMarker*)1234567890",            
+            System.IO.Path.Combine(System.Environment.CurrentDirectory, @"UnitTestsResources\MockTypeProviders\DefinitionLocationAttribute.dll"),
+            "(*ColumnMarker*)")
+
+        // This test case checks the type with space in between like N.``T T`` for GotoDefinition
+        let ``Type.SpaceInTheType``() = 
+             VerifyGoToDefnSuccessAtStartOfMarkerColumn("""
+                let a = typeof<N.``T T``>
+                // A0(*ColumnMarker*)1234567890
+                // B01234567890
+                // C01234567890 """,
+            "T``",
+            "// A0(*ColumnMarker*)1234567890",
+            System.IO.Path.Combine(System.Environment.CurrentDirectory, @"UnitTestsResources\MockTypeProviders\DefinitionLocationAttributeWithSpaceInTheType.dll"),
+            "(*ColumnMarker*)") 
+        
+        // Basic scenario on a provided Constructor
+        let ``Constructor.BasicScenario``() = 
+            
+            VerifyGoToDefnSuccessAtStartOfMarkerColumn(""" 
+                let foo = new N.T(*GotoValDef*)()
+                // A0(*ColumnMarker*)1234567890
+                // B01234567890
+                // C01234567890 """,
+            "T(*GotoValDef*)",
+             "// A0(*ColumnMarker*)1234567890",            
+            System.IO.Path.Combine(System.Environment.CurrentDirectory, @"UnitTestsResources\MockTypeProviders\DefinitionLocationAttribute.dll"),
+            "(*ColumnMarker*)")
+          
+        // Basic scenario on a provided Method
+        let ``Method.BasicScenario``() = 
+            VerifyGoToDefnSuccessAtStartOfMarkerColumn("""
+                let t = new N.T.M(*GotoValDef*)()
+                // A0(*ColumnMarker*)1234567890
+                // B01234567890
+                // C01234567890 """,
+            "M(*GotoValDef*)",
+             "// A0(*ColumnMarker*)1234567890",            
+            System.IO.Path.Combine(System.Environment.CurrentDirectory, @"UnitTestsResources\MockTypeProviders\DefinitionLocationAttribute.dll"),
+            "(*ColumnMarker*)")
+        
+        // Basic scenario on a provided Property
+        let ``Property.BasicScenario``() = 
+            VerifyGoToDefnSuccessAtStartOfMarkerColumn(""" 
+                let p = N.T.StaticProp(*GotoValDef*)
+                // A0(*ColumnMarker*)1234567890
+                // B01234567890
+                // C01234567890 """,
+            "StaticProp(*GotoValDef*)",
+             "// A0(*ColumnMarker*)1234567890",            
+            System.IO.Path.Combine(System.Environment.CurrentDirectory, @"UnitTestsResources\MockTypeProviders\DefinitionLocationAttribute.dll"),
+            "(*ColumnMarker*)")
+        
+        // Basic scenario on a provided Event
+        let ``Event.BasicScenario``() = 
+            VerifyGoToDefnSuccessAtStartOfMarkerColumn(""" 
+                let t = new N.T()
+                t.Event1(*GotoValDef*)
+                // A0(*ColumnMarker*)1234567890
+                // B01234567890
+                // C01234567890 """,
+            "Event1(*GotoValDef*)",
+             "// A0(*ColumnMarker*)1234567890",            
+            System.IO.Path.Combine(System.Environment.CurrentDirectory, @"UnitTestsResources\MockTypeProviders\DefinitionLocationAttribute.dll"),
+            "(*ColumnMarker*)")
+        
+        // Actually execute all the scenarios...      
+        ``Type.BasicScenario``()
+        ``Type.SpaceInTheType``()
+        ``Constructor.BasicScenario``()
+        ``Method.BasicScenario``()
+        ``Property.BasicScenario``()
+        ``Event.BasicScenario``()
+
+    
+    [<Test>]
+    member public this.``GotoDefinition.NoSourceCodeAvailable``() = 
+        this.VerifyGoToDefnFailAtStartOfMarker
+            (
+                fileContents = "System.String.Format(\"\")",
+                marker = "ormat",
+                f = (fun (_, result) ->
+                    Assert.IsFalse(result.Success)
+                    Assert.IsTrue(result.ErrorDescription.Contains("Source code is not available"))
+                    )
+            )
+    
+    [<Test>]
+    member public this.``GotoDefinition.NoIdentifierAtLocation``() = 
+        let useCases = 
+            [
+                "let x = 1", "1"
+                "let x = 1.2", ".2"
+                "let x = \"123\"", "2"
+            ]
+        for (source, marker) in useCases do
+            this.VerifyGoToDefnFailAtStartOfMarker
+                (
+                    fileContents = source,
+                    marker = marker,
+                    f = (fun (_, result) ->
+                        Assert.IsFalse(result.Success)
+                        Assert.IsTrue(result.ErrorDescription.Contains("Cursor is not on identifier"))
+                        )
+                )
+
+    [<Test>]
+    member public this.``GotoDefinition.ProvidedTypeNoDefinitionLocationAttribute``() =  
+
+        this.VerifyGoToDefnFailAtStartOfMarker
+            (
+                fileContents = """
+                type T = N1.T<"", 1>
+                """,
+                marker = "T<",
+                f = (fun (_, result) ->
+                    Assert.IsFalse(result.Success)
+                    Assert.IsTrue(result.ErrorDescription.Contains("provided type 'T'"))
+                    ),
+                addtlRefAssy = [System.IO.Path.Combine(System.Environment.CurrentDirectory, @"UnitTestsResources\MockTypeProviders\DummyProviderForLanguageServiceTesting.dll")]
+            )
+        
+    [<Test>]
+    member public this.``GotoDefinition.ProvidedMemberNoDefinitionLocationAttribute``() = 
+        let useCases = 
+            [
+                """
+                type T = N1.T<"", 1>
+                T.Param1
+                """, "ram1", "Param1"
+
+                """
+                type T = N1.T1
+                T.M1(1)
+                """, "1(", "M1"
+            ]
+
+        for (source, marker, name) in useCases do
+            this.VerifyGoToDefnFailAtStartOfMarker
+                (
+                    fileContents = source,
+                    marker = marker,
+                    f = (fun (_, result) ->
+                        Assert.IsFalse(result.Success)
+                        let expectedText = sprintf "provided member '%s'" name
+                        Assert.IsTrue(result.ErrorDescription.Contains(expectedText))
+                        ),
+                    addtlRefAssy = [System.IO.Path.Combine(System.Environment.CurrentDirectory, @"UnitTestsResources\MockTypeProviders\DummyProviderForLanguageServiceTesting.dll")]
+                )
+    [<Test>]
+    [<Category("TypeProvider")>]
+    [<Category("TypeProvider.DefinitionLocationAttribute.Negative")>]
+    // This test case is when the TypeProviderDefinitionLocationAttribute filepath doesn't exist  for TypeProvider Type
+    member public this.``GotoDefinition.TypeProvider.DefinitionLocationAttribute.Type.FileDoesnotExist``() =
+        this.VerifyGoToDefnFailAtStartOfMarker(
+            fileContents = """
+                let a = typeof<N.T(*GotoValDef*)>
+                // A0(*Marker*)1234567890
+                // B01234567890
+                // C01234567890 """,
+            marker = "T(*GotoValDef*)",
+            addtlRefAssy = [System.IO.Path.Combine(System.Environment.CurrentDirectory, @"UnitTestsResources\MockTypeProviders\DefinitionLocationAttributeFileDoesnotExist.dll")])
+
+    [<Test>]
+    [<Category("TypeProvider")>]
+    [<Category("TypeProvider.DefinitionLocationAttribute.Negative")>]
+    [<Ignore("Need some work to detect the line doesnot exist.")>]
+    //This test case is when the TypeProviderDefinitionLocationAttribute Line doesn't exist  for TypeProvider Type
+    member public this.``GotoDefinition.TypeProvider.DefinitionLocationAttribute.Type.LineDoesnotExist``() =
+        this.VerifyGoToDefnFailAtStartOfMarker(
+            fileContents = """
+                let a = typeof<N.T(*GotoValDef*)>
+                // A0(*Marker*)1234567890
+                // B01234567890
+                // C01234567890 """,
+            marker = "T(*GotoValDef*)",
+            addtlRefAssy = [System.IO.Path.Combine(System.Environment.CurrentDirectory, @"UnitTestsResources\MockTypeProviders\DefinitionLocationAttributeLineDoesnotExist.dll")])
+     
+    [<Test>]
+    [<Category("TypeProvider")>]
+    [<Category("TypeProvider.DefinitionLocationAttribute.Negative")>]
+    // This test case is when the TypeProviderDefinitionLocationAttribute filepath doesn't exist  for TypeProvider Constructor
+    member public this.``GotoDefinition.TypeProvider.DefinitionLocationAttribute.Constructor.FileDoesnotExist``() =
+        this.VerifyGoToDefnFailAtStartOfMarker(
+            fileContents = """
+                let foo = new N.T(*GotoValDef*)()
+                // A0(*Marker*)1234567890
+                // B01234567890
+                // C01234567890 """,
+            marker = "T(*GotoValDef*)",
+            addtlRefAssy = [System.IO.Path.Combine(System.Environment.CurrentDirectory, @"UnitTestsResources\MockTypeProviders\DefinitionLocationAttributeFileDoesnotExist.dll")])
+
+
+         
+    [<Test>]
+    [<Category("TypeProvider")>]
+    [<Category("TypeProvider.DefinitionLocationAttribute.Negative")>]
+    //This test case is when the TypeProviderDefinitionLocationAttribute filepath doesn't exist  for TypeProvider Method
+    member public this.``GotoDefinition.TypeProvider.DefinitionLocationAttribute.Method.FileDoesnotExist``() =
+        this.VerifyGoToDefnFailAtStartOfMarker(
+            fileContents = """ 
+                let t = new N.T.M(*GotoValDef*)()
+                // A0(*Marker*)1234567890
+                // B01234567890
+                // C01234567890  """,
+            marker = "M(*GotoValDef*)",
+            addtlRefAssy = [System.IO.Path.Combine(System.Environment.CurrentDirectory, @"UnitTestsResources\MockTypeProviders\DefinitionLocationAttributeFileDoesnotExist.dll")])
+
+    [<Test>]
+    [<Category("TypeProvider")>]
+    [<Category("TypeProvider.DefinitionLocationAttribute.Negative")>]
+    // This test case is when the TypeProviderDefinitionLocationAttribute filepath doesn't exist  for TypeProvider Property
+    member public this.``GotoDefinition.TypeProvider.DefinitionLocationAttribute.Property.FileDoesnotExist``() =
+        this.VerifyGoToDefnFailAtStartOfMarker(
+            fileContents = """ 
+                let p = N.T.StaticProp(*GotoValDef*)
+                // A0(*Marker*)1234567890
+                // B01234567890
+                // C01234567890 """,
+            marker = "StaticProp(*GotoValDef*)",
+            addtlRefAssy = [System.IO.Path.Combine(System.Environment.CurrentDirectory, @"UnitTestsResources\MockTypeProviders\DefinitionLocationAttributeFileDoesnotExist.dll")])
+    
+    [<Test>]
+    [<Category("TypeProvider")>]
+    [<Category("TypeProvider.DefinitionLocationAttribute.Negative")>]
+    //This test case is when the TypeProviderDefinitionLocationAttribute filepath doesn't exist  for TypeProvider Event
+    member public this.``GotoDefinition.TypeProvider.DefinitionLocationAttribute.Event.FileDoesnotExist``() =
+        this.VerifyGoToDefnFailAtStartOfMarker(
+            fileContents = """ 
+                let t = new N.T()
+                t.Event1(*GotoValDef*)
+                // A0(*Marker*)1234567890
+                // B01234567890
+                // C01234567890 """,
+            marker = "Event1(*GotoValDef*)",
+            addtlRefAssy = [System.IO.Path.Combine(System.Environment.CurrentDirectory, @"UnitTestsResources\MockTypeProviders\DefinitionLocationAttributeFileDoesnotExist.dll")])
+
+    [<Test>]
+    member public this.``ModuleDefintion``() =
+        this.VerifyGoToDefnSuccessAtStartOfMarker(
+            fileContents = """
+                //regretion test for bug 2517
+                module Foo (*MarkerModuleDefinition*) =
+                  let x = ()
+                """,
+            marker = "Foo (*MarkerModuleDefinition*)",
+            definitionCode = "module Foo (*MarkerModuleDefinition*) =")
+
+    [<Test>]
+    member public this.``Record.Field.Defintion``() = 
+        this.VerifyGoToDefnSuccessAtStartOfMarker(
+            fileContents = """
+                //regretion test for bug 2518
+                type MyRec =
+                  { myX (*MarkerXFieldDefinition*) : int
+                    myY (*MarkerYFieldDefinition*) : int
+                  }
+                let rDefault =
+                  { myX (*MarkerXField*) = 2
+                    myY (*MarkerYField*) = 3
+                  }
+                """,      
+            marker = "myX (*MarkerXFieldDefinition*)",   
+            definitionCode = "{ myX (*MarkerXFieldDefinition*) : int")
+
+    [<Test>]
+    member public this.``Record.Field.Usage``() = 
+        this.VerifyGoToDefnSuccessAtStartOfMarker(
+            fileContents = """
+                //regretion test for bug 2518
+                type MyRec =
+                  { myX (*MarkerXFieldDefinition*) : int
+                    myY (*MarkerYFieldDefinition*) : int
+                  }
+                let rDefault =
+                  { myX (*MarkerXField*) = 2
+                    myY (*MarkerYField*) = 3
+                  }
+                """,
+            marker = "myY (*MarkerYField*)",
+            definitionCode = " myY (*MarkerYFieldDefinition*) : int")
+
+    /// run a GotoDefinition test where the expected result is a file that we
+    /// have an `OpenFile` handle for (this won't work, e.g., if this file is a
+    /// generated .fsi that (potentially) doesn't yet exist)
+
+    /// exp  = (<identifier where cursor ought to be>, <whole line where cursor ought to be>, <name of file that's expected>) option
+    /// file = <file to gotodefinition in>
+    /// act  = <the result of the GotoDefinition call>
+    member internal this.GotoDefinitionCheckResultAgainst (exp : (string * string * string) option)(file : OpenFile)(act : GotoDefnResult) : unit =
+      match (exp, act.ToOption()) with
+      | (Some (toFind, expLine, expFile), Some (span, actFile)) -> printfn "%s" "Result received, as expected; checking."
+                                                                   Assert.AreEqual (expFile, actFile)
+                                                                   printfn "%s" "Filename matches expected."
+                                                                   MoveCursorTo(file, span.iStartLine + 1, span.iStartIndex + 1) // adjust & move to the identifier
+                                                                   match GetIdentifierAtCursor file with // REVIEW: actually check that we're on the leftmost character of the identifier
+                                                                   | None         -> Assert.Fail("No identifier at cursor!")
+                                                                   | Some (id, _) -> Assert.AreEqual (toFind, id) // are we on the identifier we expect?
+                                                                                     printfn "%s" "Identifier at cursor matches expected."
+                                                                                     Assert.AreEqual (expLine.Trim (), (span.iStartLine |> (+) 1 |> GetLineNumber file).Trim ()) // ignore initial- / final-whitespace-introduced noise; adjust for difference in index numbers
+                                                                                     printfn "%s" "Line at cursor matches expected."
+      | (None,                            None)                 -> printfn "%s" "No result received, as expected." // sometimes we may expect GotoDefinition to fail, e.g., when the cursor isn't placed on a valid position (i.e., over an identifier, and, maybe, a constant if we decide to support that)
+      | (Some _,                          None)                 -> Assert.Fail("No result received, but one was expected!") // distinguish this and the following case to give insight in case of failure
+      | (None,                            Some _)               -> Assert.Fail("Result received, but none was expected!")
+
+    /// this can be used when we don't have the expected file open; we still
+    /// need its name
+
+    /// exp = (<identifier where cursor ought to be>, <name of file that's expected>) option
+    member internal this.GotoDefinitionCheckResultAgainstAnotherFile (proj : OpenProject)(exp : (string * string) option)(act : GotoDefnResult) : unit =
+      match (exp, act.ToOption()) with
+      | (Some (toFind, expFile), Some (span, actFile)) -> printfn "%s" "Result received, as expected; checking."
+                                                          Assert.AreEqual (expFile, Path.GetFileName actFile)
+                                                          printfn "%s" "Filename matches expected."
+                                                          let file = OpenFile (proj, actFile)
+                                                          let line = span.iStartLine |> ((+) 1) |> GetLineNumber file // need to adjust line number here
+                                                          Assert.AreEqual (toFind, line.Substring (span.iStartIndex, toFind.Length))
+                                                          printfn "%s" "Identifier at cursor matches expected."
+      | (None,                   None)                 -> printfn "%s" "No result received, as expected." // sometimes we may expect GotoDefinition to fail, e.g., when the cursor isn't placed on a valid position (i.e., over an identifier, and, maybe, a constant if we decide to support that)
+      | (Some _,                 None)                 -> Assert.Fail("No result received, but one was expected!") // distinguish this and the following case to give insight in case of failure
+      | (None,                   Some _)               -> Assert.Fail("Result received, but none was expected!")
+
+    /// exp = (<expected line>, <expected identifier>) option
+    member this.GotoDefinitionTestWithSimpleFile (startLoc : string)(exp : (string * string) option) : unit =
+        this.SolutionGotoDefinitionTestWithSimpleFile startLoc exp 
+
+    [<Test>]
+    member this.``GotoDefinition.OverloadResolution``() =
+        let lines =
+          [ "type D() ="
+            "   override this.#3#ToString() = System.String.Empty"
+            "   member this.#4#ToString(s : string) = ()"
+            ""
+            "   member this.#1#Foo() = ()"
+            "   member this.#2#Foo(x) = ()"
+            ""
+            "let d = new D()"
+            "d.Foo$1$()"
+            "d.Foo$2$(1)"
+            "d.ToString$3$()"
+            "d.ToString$4$(\"aaa\") "
+          ]
+        this.GotoDefinitionTestWithMarkup lines
+    [<Test>]
+    member this.``GotoDefinition.OverloadResolutionForProperties``() =
+        let lines = [ "type D() ="
+                      "  member this.Foo"
+                      "    with #1##2#get(i:int) = 1"
+                      "    and set (i:int) v = ()"
+                      ""
+                      "  member this.Foo"
+                      "    with #3##4#get (s:string) = 1"
+                      "    and  set (s:string) v = ()"
+                      ""
+                      "D().$1$Foo 1"
+                      "D().$2$Foo 1 <- 2"
+                      "D().$3$Foo \"abc\""
+                      "D().$4$Foo \"abc\" <- 2"
+            ]
+        this.GotoDefinitionTestWithMarkup lines
+
+    [<Test>]
+    member this.``GotoDefinition.OverloadResolutionWithOverrides``() =
+        let lines =
+          [ "[<AbstractClass>]"
+            "type Base<'T>() ="
+            "   member this.#2#Method() = ()"
+            "   abstract Method : 'T -> unit"
+            ""
+            "type Derived() ="
+            "   inherit Base<int>()"
+            ""
+            "   override this.#1#Method (i:int) = ()"
+            ""
+            "let d = new Derived()"
+            "d.$1$Method 12"
+            "d.$2$Method()"
+          ]
+        this.GotoDefinitionTestWithMarkup lines
+
+    [<Test>]
+    member this.``GotoDefinition.OverloadResolutionStatics``() =
+        let lines =
+          [   "type T ="
+              "   static member #1#Foo(i : int) = ()"
+              "   static member #2#Foo(s : string) = ()"
+              ""
+              "T.$1$Foo 1"
+              "T.$2$Foo \"abc\""
+          ]
+        this.GotoDefinitionTestWithMarkup lines
+
+    [<Test>]
+    member this.``GotoDefinition.Constructors``() =
+        let lines =
+          [   "type #1a##1b##1c##1d#B() ="
+              "  #2a##2b##2c##2d#new(i : int) = B()"
+              "  #3a##3b##3c##3d#new(s : string) = B()"
+              ""
+              "B()"
+              "B(1)"
+              "B(\"abc\")"
+              ""
+              "new $1b$B()"
+              "new $2b$B(1)"
+              "new $3b$B(\"abc\")"
+              ""
+              "type D1() ="
+              "    inherit $1c$B()"
+              ""
+              "type D2() ="
+              "    inherit $2c$B(1)"
+
+              "type D3() ="
+              "    inherit $3c$B(\"abc\")"
+              ""
+              "let o1 = { new $1d$B() with"
+              "             override this.ToString() = \"\""
+              "         }"
+              "let o2 = { new $2d$B(1) with"
+              "             override this.ToString() = \"\""
+              "        }"
+              "let o2 = { new $3d$B(\"aaa\") with"
+              "             override this.ToString() = \"\""
+              "         }"
+
+          ]
+        this.GotoDefinitionTestWithMarkup lines
+
+    member internal this.GotoDefinitionTestWithMarkup (lines : string list) =      
+      let origins = Dictionary<string, int*int>()
+      let targets = Dictionary<string, int*int>()
+      let lines =
+        [   let lineNo = ref 0
+            for l in lines do
+                let builder = new System.Text.StringBuilder(l)
+                let cont = ref true
+                while !cont do
+                    let s = builder.ToString()
+                    let index = s.IndexOfAny([|'$';'#'|])
+                    if index < 0 then
+                        cont := false
+                    else
+                        let c = s.[index]
+                        let nextIndex = s.IndexOf(c, index+1) 
+                        let marker = s.Substring(index+1, nextIndex - (index+1))
+                        if c = '$' then 
+                            origins.Add(marker, (!lineNo+1,index+1)) // caret positions are 1-based, but...
+                        else 
+                            targets.Add(marker, (!lineNo,index)) // ...spans are 0-based. Argh. Thank you, Salsa!
+                        builder.Remove(index, nextIndex - index + 1) |> ignore
+                yield builder.ToString()
+                lineNo := !lineNo + 1
+        ]
+
+      let (_, _, file) = this.CreateSingleFileProject(lines)
+
+      for KeyValue(marker,(line,col)) in origins do
+          MoveCursorTo(file, line, col)
+          let res = GotoDefinitionAtCursor file
+          match res.ToOption() with
+          |   None -> Assert.IsFalse(targets.ContainsKey(marker), sprintf "%s: definition not found " marker)
+          |   Some (span,text) ->
+                  match targets.TryGetValue(marker) with
+                  |   false, _ ->  Assert.Fail(sprintf "%s: unexpected definition found" marker)
+                  |   true, (line1, col1) -> 
+                          Assert.IsTrue(span.iStartIndex = col1 && span.iStartLine = line1, 
+                                sprintf "%s: wrong definition found expected %d %d but found %d %d %s" marker line1 col1 span.iStartLine span.iStartIndex text )
+
+    
+    /// exp = (<expected line>, <expected identifier>) option
+    member internal this.SolutionGotoDefinitionTestWithSimpleFile (startLoc : string)(exp : (string * string) option) : unit =
+      let lines = 
+        [ "#light"
+          "let _ = 3"
+          "let _ = \"hi\""
+          "let _ = 2 + 3"
+          "let _ = []"
+          "let _ = ()"
+          "let _ = null"
+          "let _ ="
+          "  let x = () (*loc-2*)"
+          "  x (*loc-1*)"
+          "let _ ="
+          "  let x = () (*loc-5*)"
+          "  let x = () (*loc-3*)"
+          "  x (*loc-4*)"
+          "let _ ="
+          "  let x = () (*loc-7*)"
+          "  let x ="
+          "    x (*loc-6*)"
+          "  ()"
+          "let _ ="
+          "  let     x = ()"
+          "  let rec x = (*loc-9*)"
+          "    fun y -> (*loc-10*)"
+          "      x y (*loc-8*)"
+          "  ()"
+          "let _ ="
+          "  let (+) x _ = x (*loc-12*)"
+          "  2 + 3 (*loc-11*)"
+          "type Zero = (*loc-13*)"
+          "let foo (_ : Zero) : 'a = failwith \"hi\" (*loc-14*)"
+          "type One = (*loc-16*)"
+          "  One (*loc-15*)"
+          "let f (x : One) = (*loc-17*)"
+          "  One (*loc-18*)"
+          "type Nat = (*loc-19*)"
+          "  | Suc of Nat (*loc-20*)"
+          "  | Zro (*loc-21*)"
+          "let rec plus m n = (*loc-23*)"
+          "  match m with (*loc-22*)"
+          "  | Zro   -> (*loc-24*)"
+          "      n"
+          "  | Suc m -> (*loc-25*)"
+          "      Suc (plus m n) (*loc-26*)"
+          "type MyRec = (*loc-27*)"
+          "  { myX : int (*loc-28*)"
+          "    myY : int (*loc-29*)"
+          "  }"
+          "let rDefault ="
+          "  { myX = 2 (*loc-30*)"
+          "    myY = 3 (*loc-31*)"
+          "  }"
+          "let _ = { rDefault with myX = 7 } (*loc-32*)"
+          "let _ ="
+          "  let a = 2"
+          "  let id (x : 'a) (*loc-33*)"
+          "    : 'a = x (*loc-34*)"
+          "  ()"
+          "let _ ="
+          "  let foo          = ()"
+          "  let f (_ as foo) = (*loc-35*)"
+          "    foo (*loc-36*)"
+          "  ()"
+          "let _ ="
+          "  let foo          = ()"
+          "  let f (x as foo) = foo"
+          "  ()"
+          "let _ ="
+          "  fun x (*loc-37*)"
+          "      x -> (*loc-38*)"
+          "    x (*loc-39*)"
+          "let _ ="
+          "  let f = () (*loc-40*)"
+          "  let f = (*loc-41*)"
+          "    function f -> (*loc-42*)"
+          "      f (*loc-43*)"
+          "  ()"
+          "let _ ="
+          "  let f x ="
+          "    match x with"
+          "    | Suc x (*loc-44*)"
+          "    | x (*loc-45*) -> "
+          "        x"
+          "  ()"
+          "let _ ="
+          "  let f x ="
+          "    match x with"
+          "    | Suc y & z -> (*loc-47*)"
+          "        y (*loc-46*)"
+          "  ()"
+          "let _ ="
+          "  let f xs ="
+          "    match xs with"
+          "    | x :: xs -> (*loc-49*)"
+          "        x (*loc-48*)"
+          "    | _       -> []"
+          "  ()"
+          "let _ ="
+          "  let f x ="
+          "    match x with"
+          "    | (y : int, z) -> (*loc-51*)"
+          "         y (*loc-50*)"
+          "  ()"
+          "let _ ="
+          "  let f xs ="
+          "    match xs with"
+          "    | x :: xs (*loc-54*)"
+          "      when xs <> [] -> (*loc-52*)"
+          "        x :: xs (*loc-53*)"
+          "  ()"
+          "module Too = (*loc-55*)"
+          "  let foo = 0 (*loc-56*)"
+          "module Bar ="
+          "  open Too (*loc-57*)"
+          "let _ = Too.foo (*loc-58*)"
+          "module Overlap ="
+          "  type Parity = Even | Odd"
+          "  let (|Even|Odd|) x = (*loc-59*)"
+          "    if x % 0 = 0"
+          "       then Even (*loc-60*)"
+          "       else Odd"
+          "  let foo (x : int) ="
+          "    match x with"
+          "    | Even -> 1 (*loc-61*)"
+          "    | Odd  -> 0"
+          "  let patval = (|Even|Odd|) (*loc-61b*)"
+          "let _ ="
+          "  op_Addition 2 2"
+          "type Class () = (*loc-62*)"
+          "  member c.Method () = () (*loc-63*)"
+          "  static member Foo () = () (*loc-64*)"
+          "let _ ="
+          "  let c = Class () (*loc-65*)"
+          "  c.Method () (*loc-66*)"
+          "  Class.Foo () (*loc-67*)"
+          "type Class' () ="
+          "  member c.Method  () = c.Method () (*loc-68*)"
+          "  member c.Method1 () = c.Method2 () (*loc-69*)"
+          "  member c.Method2 () = c.Method1 () (*loc-70*)"
+          "  member c.Method3  () ="
+          "    let c = Class ()"
+          "    c.Method () (*loc-71*)"
+          "type Colors = Red   = 1"
+          "            | White = 2"
+          "            | Blue  = 3"
+          "let _ = Colors.Red"
+          "let _ ="
+          "  let x = 2"
+          "  \"x(*loc-72*)\""
+          "let _ ="
+          "  let x = 2"
+          "  \"this is a string"
+          "    x(*loc-73*)"
+          "  \""
+          "let _ ="
+          "  let rec ``let`` = (*loc-74*)"
+          "    function 0 -> 1"
+          "           | n -> n * ``let`` (n - 1) (*loc-75*)"
+          "let id77 = 0"  
+          "type C ="
+          "  val id77 (*loc-77*) : int"
+        ]
+      this.SolutionGotoDefinitionTestWithLines lines startLoc exp
+
+
+
+
+    member internal this.SolutionGotoDefinitionTestWithLines lines (startLoc : string)(exp : (string * string) option) : unit =        
+      // The test itself
+      let (_, _, file) = this.CreateSingleFileProject(lines)
+      let fnm = 
+        GetNameOfOpenFile file
+        |> Path.GetFileName
+      MoveCursorToStartOfMarker (file, startLoc)
+      let res = GotoDefinitionAtCursor file |> this.GotoDefinitionFixupFilename
+      match exp with
+      | None              -> this.GotoDefinitionCheckResultAgainst None                     file res
+      | Some (endLoc, id) -> this.GotoDefinitionCheckResultAgainst (Some (id, endLoc, fnm)) file res
+
+    /// exp = (<identifier where cursor ought to be>, <name of file that's expected>) option
+    member this.GotoDefinitionTestWithLib (startLoc : string)(exp : (string * string) option) : unit =
+      let lines = [ "let _ = List.map (*loc-1*)" ]
+      let (_, proj, file) = this.CreateSingleFileProject(lines)
+
+      MoveCursorToStartOfMarker (file, startLoc)
+      let res = GotoDefinitionAtCursor file
+      this.GotoDefinitionCheckResultAgainstAnotherFile proj exp res
+
+    member this.GotoDefinitionFixupFilename (x : GotoDefnResult) : GotoDefnResult =
+      if x.Success then 
+        GotoDefnResult.MakeSuccess(Path.GetFileName x.Url, x.Span) 
+      else 
+        GotoDefnResult.MakeError(x.ErrorDescription)
+
+    // the format of the comments for each test displays the desired behaviour,
+    // where `$` and `#` indicate the initial and final cursor positions,
+    // respectively; if the two are the same then the `#` is omitted
+
+    // the `loc-<number>` comments in the source used for the tests are to
+    // ensure that we've found the correct position (i.e., these must be unique
+    // in any given test source file)
+
+    [<Test>]
+    member this.``GotoDefinition.InheritedMembers``() =
+        let lines =
+            [ "[<AbstractClass>]"
+              "type Foo() ="
+              "   abstract Method : unit -> unit"
+              "   abstract Property : int"
+              "type Bar() ="
+              "   inherit Foo()"
+              "   override this.Method () = ()"
+              "   override this.Property = 1"
+              "let b = Bar()"
+              "b.Method(*loc-1*)()"
+              "b.Property(*loc-2*)"
+            ]
+        this.SolutionGotoDefinitionTestWithLines lines  "Method(*loc-1*)" (Some("override this.Method () = ()","this.Method"))
+        this.SolutionGotoDefinitionTestWithLines lines  "Property(*loc-2*)" (Some("override this.Property = 1","this.Property"))
+
+
+    /// let #x = () in $x
+    [<Test>]
+    [<Category("PerfCheck")>]
+    member public this.``GotoDefinition.InsideClass.Bug3176`` () =
+      this.GotoDefinitionTestWithSimpleFile "id77 (*loc-77*)" (Some("val id77 (*loc-77*) : int", "id77"))
+
+    /// let #x = () in $x
+    [<Test>]
+    member public this.``GotoDefinition.Simple.Binding.TrivialLetRHS`` () =
+      this.GotoDefinitionTestWithSimpleFile "x (*loc-1*)" (Some("let x = () (*loc-2*)", "x"))
+
+    /// let #x = () in x$
+    [<Test>]
+    member public this.``GotoDefinition.Simple.Binding.TrivialLetRHSToRight`` () =
+      this.GotoDefinitionTestWithSimpleFile " (*loc-1*)" (Some("let x = () (*loc-2*)", "x"))
+
+    /// let $x = () in x
+    [<Test>]
+    member public this.``GotoDefinition.Simple.Binding.TrivialLetLHS`` () =
+      this.GotoDefinitionTestWithSimpleFile "x = () (*loc-2*)" (Some("let x = () (*loc-2*)", "x"))
+
+    /// let x = () in let #x = () in $x
+    [<Test>]
+    member public this.``GotoDefinition.Simple.Binding.NestedLetWithSameNameRHS`` () =
+      this.GotoDefinitionTestWithSimpleFile "x (*loc-4*)" (Some("let x = () (*loc-3*)", "x"))
+
+    /// let x = () in let $x = () in x
+    [<Test>]
+    member public this.``GotoDefinition.Simple.Binding.NestedLetWithSameNameLHSInner`` () =
+      this.GotoDefinitionTestWithSimpleFile "x = () (*loc-3*)" (Some("let x = () (*loc-3*)", "x"))
+
+    /// let $x = () in let x = () in x
+    [<Test>]
+    member public this.``GotoDefinition.Simple.Binding.NestedLetWithSameNameLHSOuter`` () =
+      this.GotoDefinitionTestWithSimpleFile "x = () (*loc-5*)" (Some("let x = () (*loc-5*)", "x"))
+
+    /// let #x = () in let x = $x in ()
+    [<Test>]
+    member public this.``GotoDefinition.Simple.Binding.NestedLetWithXIsX`` () =
+      this.GotoDefinitionTestWithSimpleFile "x (*loc-6*)" (Some("let x = () (*loc-7*)", "x"))
+
+    /// let x = () in let rec #x = fun y -> $x y in ()
+    [<Test>]
+    member public this.``GotoDefinition.Simple.Binding.NestedLetWithXRec`` () =
+      this.GotoDefinitionTestWithSimpleFile "x y (*loc-8*)" (Some("let rec x = (*loc-9*)", "x"))
+
+    /// let x = () in let rec x = fun #y -> x $y in ()
+    [<Test>]
+    member public this.``GotoDefinition.Simple.Binding.NestedLetWithXRecParam`` () =
+      this.GotoDefinitionTestWithSimpleFile "y (*loc-8*)" (Some("fun y -> (*loc-10*)", "y"))
+
+    /// let #(+) x _ = x in 2 $+ 3
+    [<Test>]
+    [<Ignore "Bug 2514 filed.">]
+    member public this.``GotoDefinition.Simple.Binding.Operator`` () =
+      this.GotoDefinitionTestWithSimpleFile "+ 3 (*loc-11*)" (Some("let (+) x _ = x (*loc-2*)", "+"))
+
+    /// type #Zero =
+    /// let f (_ : $Zero) = 0
+    [<Test>]
+    member public this.``GotoDefinition.Simple.Datatype.NullType`` () =
+      this.GotoDefinitionTestWithSimpleFile "Zero) : 'a = failwith \"hi\" (*loc-14*)" (Some("type Zero = (*loc-13*)", "Zero"))
+
+    /// type One = $One
+    [<Test>]
+    member public this.``GotoDefinition.Simple.Datatype.UnitTypeConsDef`` () =
+      this.GotoDefinitionTestWithSimpleFile "One (*loc-15*)" (Some("One (*loc-15*)", "One"))
+
+    /// type $One = One
+    [<Test>]
+    member public this.``GotoDefinition.Simple.Datatype.UnitTypeTypenameDef`` () =
+      this.GotoDefinitionTestWithSimpleFile "One = (*loc-16*)" (Some("type One = (*loc-16*)", "One"))
+
+    /// type One = #One
+    /// let f (_ : One) = $One
+    [<Test>]
+    member public this.``GotoDefinition.Simple.Datatype.UnitTypeCons`` () =
+      this.GotoDefinitionTestWithSimpleFile "One (*loc-18*)" (Some("One (*loc-15*)", "One"))
+
+    /// type #One = One
+    /// let f (_ : $One) = One
+    [<Test>]
+    member public this.``GotoDefinition.Simple.Datatype.UnitTypeTypename`` () =
+      this.GotoDefinitionTestWithSimpleFile "One) = (*loc-17*)" (Some("type One = (*loc-16*)", "One"))
+
+    /// type $Nat = Suc of Nat | Zro
+    [<Test>]
+    member public this.``GotoDefinition.Simple.Datatype.NatTypeTypenameDef`` () =
+      this.GotoDefinitionTestWithSimpleFile "Nat = (*loc-19*)" (Some("type Nat = (*loc-19*)", "Nat"))
+
+    /// type #Nat = Suc of $Nat | Zro
+    [<Test>]
+    member public this.``GotoDefinition.Simple.Datatype.NatTypeConsArg`` () =
+      this.GotoDefinitionTestWithSimpleFile "Nat (*loc-20*)" (Some("type Nat = (*loc-19*)", "Nat"))
+
+    /// type Nat = Suc of Nat | #Zro
+    /// fun m -> match m with | $Zro -> () | _ -> ()
+    [<Test>]
+    member public this.``GotoDefinition.Simple.Datatype.NatPatZro`` () =
+      this.GotoDefinitionTestWithSimpleFile "Zro   -> (*loc-24*)" (Some("| Zro (*loc-21*)", "Zro"))
+
+    /// type Nat = $Suc of Nat | Zro
+    /// fun m -> match m with | Zro -> () | $Suc _ -> ()
+    [<Test>]
+    member public this.``GotoDefinition.Simple.Datatype.NatPatSuc`` () =
+      this.GotoDefinitionTestWithSimpleFile "Suc m -> (*loc-25*)" (Some("| Suc of Nat (*loc-20*)", "Suc"))
+
+    /// let rec plus m n = match m with | Zro -> n | Suc #m -> Suc (plus $m n)
+    [<Test>]
+    member public this.``GotoDefinition.Simple.Datatype.NatPatSucVarUse`` () =
+      this.GotoDefinitionTestWithSimpleFile "m n) (*loc-26*)" (Some("| Suc m -> (*loc-25*)", "m"))
+
+    /// let rec plus m n = match m with | Zro -> n | Suc #m -> Suc (plus $m n)
+    [<Test>]
+    member public this.``GotoDefinition.Simple.Datatype.NatPatSucOuterVarUse`` () =
+      this.GotoDefinitionTestWithSimpleFile "n) (*loc-26*)" (Some("let rec plus m n = (*loc-23*)", "n"))
+
+    /// type $MyRec = { myX : int ; myY : int }
+    [<Test>]
+    member public this.``GotoDefinition.Simple.Datatype.RecordTypenameDef`` () =
+      this.GotoDefinitionTestWithSimpleFile "MyRec = (*loc-27*)" (Some("type MyRec = (*loc-27*)", "MyRec"))
+
+    /// type MyRec = { $myX : int ; myY : int }
+    [<Test>]
+    member public this.``GotoDefinition.Simple.Datatype.RecordField1Def`` () =
+      this.GotoDefinitionTestWithSimpleFile "myX : int (*loc-28*)" (Some("{ myX : int (*loc-28*)", "myX"))
+
+    /// type MyRec = { myX : int ; $myY : int }
+    [<Test>]
+    member public this.``GotoDefinition.Simple.Datatype.RecordField2Def`` () =
+      this.GotoDefinitionTestWithSimpleFile "myY : int (*loc-29*)" (Some("myY : int (*loc-29*)", "myY"))
+
+    /// type MyRec = { #myX : int ; myY : int }
+    /// let rDefault = { $myX = 2 ; myY = 3 }
+    [<Test>]
+    member public this.``GotoDefinition.Simple.Datatype.RecordField1Use`` () =
+      this.GotoDefinitionTestWithSimpleFile "myX = 2 (*loc-30*)" (Some("{ myX : int (*loc-28*)", "myX"))
+
+    /// type MyRec = { myX : int ; #myY : int }
+    /// let rDefault = { myX = 2 ; $myY = 3 }
+    [<Test>]
+    member public this.``GotoDefinition.Simple.Datatype.RecordField2Use`` () =
+      this.GotoDefinitionTestWithSimpleFile "myY = 3 (*loc-31*)" (Some("myY : int (*loc-29*)", "myY"))
+
+    /// type MyRec = { #myX : int ; myY : int }
+    /// let rDefault = { myX = 2 ; myY = 3 }
+    /// let _ = { rDefault with $myX = 7 }
+    [<Test>]
+    member public this.``GotoDefinition.Simple.Datatype.RecordField1UseInWith`` () =
+      this.GotoDefinitionTestWithSimpleFile "myX = 7 } (*loc-32*)" (Some("{ myX : int (*loc-28*)", "myX"))
+
+
+    /// let a = () in let id (x : '$a) : 'a = x
+    [<Test>]
+    member public this.``GotoDefinition.Simple.Polymorph.Leftmost`` () =
+      this.GotoDefinitionTestWithSimpleFile "a) (*loc-33*)" None
+
+    /// let a = () in let id (x : 'a) : '$a = x
+    [<Test>]
+    member public this.``GotoDefinition.Simple.Polymorph.NotLeftmost`` () =
+      this.GotoDefinitionTestWithSimpleFile "a = x (*loc-34*)" None
+
+    /// let foo = () in let f (_ as $foo) = foo in ()
+    [<Test>]
+    member public this.``GotoDefinition.Simple.Tricky.AsPatLHS`` () =
+      this.GotoDefinitionTestWithSimpleFile "foo) = (*loc-35*)" (Some("let f (_ as foo) = (*loc-35*)", "foo"))
+
+    /// let foo = () in let f (_ as #foo) = $foo in ()
+    [<Test>]
+    member public this.``GotoDefinition.Simple.Tricky.AsPatRHS`` () =
+      this.GotoDefinitionTestWithSimpleFile "foo (*loc-36*)" (Some("let f (_ as foo) = (*loc-35*)", "foo"))
+
+    /// fun $x x -> x
+    [<Test>]
+    member public this.``GotoDefinition.Simple.Tricky.LambdaMultBind1`` () =
+      this.GotoDefinitionTestWithSimpleFile "x (*loc-37*)" (Some("fun x (*loc-37*)", "x"))
+
+    /// fun x $x -> x
+    [<Test>]
+    member public this.``GotoDefinition.Simple.Tricky.LambdaMultBind2`` () =
+      this.GotoDefinitionTestWithSimpleFile "x -> (*loc-38*)" (Some("x -> (*loc-38*)", "x"))
+
+    /// fun x $x -> x
+    [<Test>]
+    member public this.``GotoDefinition.Simple.Tricky.LambdaMultBindBody`` () =
+      this.GotoDefinitionTestWithSimpleFile "x (*loc-39*)" (Some("x -> (*loc-38*)", "x"))
+
+    /// let f = () in let $f = function f -> f in ()
+    [<Test>]
+    member public this.``GotoDefinition.Simple.Tricky.LotsOfFsFunc`` () =
+      this.GotoDefinitionTestWithSimpleFile "f = (*loc-41*)" (Some("let f = (*loc-41*)", "f"))
+
+    /// let f = () in let f = function $f -> f in ()
+    [<Test>]
+    member public this.``GotoDefinition.Simple.Tricky.LotsOfFsPat`` () =
+      this.GotoDefinitionTestWithSimpleFile "f -> (*loc-42*)" (Some("function f -> (*loc-42*)", "f"))
+
+    /// let f = () in let f = function #f -> $f in ()
+    [<Test>]
+    member public this.``GotoDefinition.Simple.Tricky.LotsOfFsUse`` () =
+      this.GotoDefinitionTestWithSimpleFile "f (*loc-43*)" (Some("function f -> (*loc-42*)", "f"))
+
+    /// let f x = match x with | Suc $x | x -> x
+    [<Test>]
+    member public this.``GotoDefinition.Simple.Tricky.OrPatLeft`` () =
+      this.GotoDefinitionTestWithSimpleFile "x (*loc-44*)" (Some("| Suc x (*loc-44*)", "x"))
+
+    /// let f x = match x with | Suc x | $x -> x
+    [<Test >]
+    member public this.``GotoDefinition.Simple.Tricky.OrPatRight`` () =
+      this.GotoDefinitionTestWithSimpleFile "x (*loc-45*)" (Some("| Suc x (*loc-44*)", "x"))  // NOTE: or-patterns bind at first occurrence of the variable
+
+    /// let f x = match x with | Suc #y & z -> $y
+    [<Test>]
+    member public this.``GotoDefinition.Simple.Tricky.AndPat`` () =
+      this.GotoDefinitionTestWithSimpleFile "y (*loc-46*)" (Some("| Suc y & z -> (*loc-47*)", "y"))
+
+    /// let f xs = match xs with | #x :: xs -> $x
+    [<Test>]
+    member public this.``GotoDefinition.Simple.Tricky.ConsPat`` () =
+      this.GotoDefinitionTestWithSimpleFile "x (*loc-48*)" (Some("| x :: xs -> (*loc-49*)", "x"))
+
+    /// let f p = match p with (#y, z) -> $y
+    [<Test>]
+    member public this.``GotoDefinition.Simple.Tricky.PairPat`` () =
+      this.GotoDefinitionTestWithSimpleFile "y (*loc-50*)" (Some("| (y : int, z) -> (*loc-51*)", "y"))
+
+    /// fun xs -> match xs with x :: #xs when $xs <> [] -> x :: xs
+    [<Test>]
+    member public this.``GotoDefinition.Simple.Tricky.ConsPatWhenClauseInWhen`` () =
+      this.GotoDefinitionTestWithSimpleFile "xs <> [] -> (*loc-52*)" (Some("| x :: xs (*loc-54*)", "xs"))
+
+    /// fun xs -> match xs with #x :: xs when xs <> [] -> $x :: xs
+    [<Test>]
+    member public this.``GotoDefinition.Simple.Tricky.ConsPatWhenClauseInWhenRhsX`` () =
+      this.GotoDefinitionTestWithSimpleFile "x :: xs (*loc-53*)" (Some("| x :: xs (*loc-54*)", "x"))
+
+    /// fun xs -> match xs with x :: #xs when xs <> [] -> x :: $xs
+    [<Test>]
+    member public this.``GotoDefinition.Simple.Tricky.ConsPatWhenClauseInWhenRhsXs`` () =
+      this.GotoDefinitionTestWithSimpleFile "xs (*loc-53*)" (Some("| x :: xs (*loc-54*)", "xs"))
+
+    /// let x = "$x"
+    [<Test>]
+    member public this.``GotoDefinition.Simple.Tricky.InStringFails`` () =
+      this.GotoDefinitionTestWithSimpleFile "x(*loc-72*)" None
+
+    /// let x = "hello
+    ///          $x
+    ///         "
+    [<Test>]
+    member public this.``GotoDefinition.Simple.Tricky.InMultiLineStringFails`` () =
+      this.GotoDefinitionTestWithSimpleFile "x(*loc-73*)" None
+
+    [<Test>]
+    member public this.``GotoDefinition.Simple.Tricky.QuotedKeyword`` () =
+      this.GotoDefinitionTestWithSimpleFile "let`` = (*loc-74*)" (Some("let rec ``let`` = (*loc-74*)", "``let``"))
+
+    /// module $Too = let foo = ()
+    [<Test>]
+    member public this.``GotoDefinition.Simple.Module.DefModname`` () =
+      this.GotoDefinitionTestWithSimpleFile "Too = (*loc-55*)" (Some("module Too = (*loc-55*)", "Too"))
+
+    /// module Too = $foo = ()
+    [<Test>]
+    member public this.``GotoDefinition.Simple.Module.DefMember`` () =
+      this.GotoDefinitionTestWithSimpleFile "foo = 0 (*loc-56*)" (Some("let foo = 0 (*loc-56*)", "foo"))
+
+    /// module #Too = foo = ()
+    /// module Bar = open $Too
+    [<Test>]
+    member public this.``GotoDefinition.Simple.Module.Open`` () =
+      this.GotoDefinitionTestWithSimpleFile "Too (*loc-57*)" (Some("module Too = (*loc-55*)", "Too"))
+
+    /// module #Too = foo = ()
+    /// $Too.foo
+    [<Test>]
+    member public this.``GotoDefinition.Simple.Module.QualifiedModule`` () =
+      this.GotoDefinitionTestWithSimpleFile "Too.foo (*loc-58*)" (Some("module Too = (*loc-55*)", "Too"))
+
+    /// module Too = #foo = ()
+    /// Too.$foo
+    [<Test>]
+    member public this.``GotoDefinition.Simple.Module.QualifiedMember`` () =
+      this.GotoDefinitionTestWithSimpleFile "foo (*loc-58*)" (Some("let foo = 0 (*loc-56*)", "foo"))
+
+    /// type Parity = Even | Odd
+    /// let (|$Even|Odd|) x = if x % 0 = 0 then Even else Odd
+    [<Test>]
+    member public this.``GotoDefinition.Simple.ActivePat.ConsDefLHS`` () =
+      this.GotoDefinitionTestWithSimpleFile "Even|Odd|) x = (*loc-59*)" (Some("let (|Even|Odd|) x = (*loc-59*)", "|Even|Odd|"))
+
+    /// type Parity = Even | Odd
+    /// let (|#Even|Odd|) x = if x % 0 = 0 then $Even else Odd
+    [<Test>]
+    member public this.``GotoDefinition.Simple.ActivePat.ConsDefRhs`` () =
+      this.GotoDefinitionTestWithSimpleFile "Even (*loc-60*)" (Some("let (|Even|Odd|) x = (*loc-59*)", "|Even|Odd|"))
+
+    /// type Parity = Even | Odd
+    /// let (|#Even|Odd|) x = if x % 0 = 0 then Even else Odd
+    /// let foo x =
+    ///   match x with
+    ///   | $Even -> 1
+    ///   | Odd  -> 0
+    [<Test>]
+    member public this.``GotoDefinition.Simple.ActivePat.PatUse`` () =
+      this.GotoDefinitionTestWithSimpleFile "Even -> 1 (*loc-61*)" (Some("let (|Even|Odd|) x = (*loc-59*)", "|Even|Odd|"))
+
+    /// let patval = (|Even|Odd|) (*loc-61b*)
+    [<Test>]
+    member public this.``GotoDefinition.Simple.ActivePat.PatUseValue`` () =
+      this.GotoDefinitionTestWithSimpleFile "en|Odd|) (*loc-61b*)" (Some("let (|Even|Odd|) x = (*loc-59*)", "|Even|Odd|"))
+
+    [<Test>]
+    [<Ignore("This is currently broken for dev enlistments.")>]
+    member public this.``GotoDefinition.Library.InitialTest`` () =
+      this.GotoDefinitionTestWithLib "map (*loc-1*)" (Some("map", "lis.fs"))
+
+    // ********** Tests of OO Stuff **********
+
+    /// type #Class$ () =
+    ///   member c.Method () = ()
+    [<Test>]
+    member public this.``GotoDefinition.ObjectOriented.ClassNameDef`` () =
+      this.GotoDefinitionTestWithSimpleFile " () = (*loc-62*)" (Some("type Class () = (*loc-62*)", "Class"))
+
+    /// type Class () =
+    ///   member c.#Method$ () = ()
+    [<Test>]
+    member public this.``GotoDefinition.ObjectOriented.ILMethodDef`` () =
+      this.GotoDefinitionTestWithSimpleFile " () = () (*loc-63*)" (Some("member c.Method () = () (*loc-63*)", "c.Method"))
+
+    /// type Class () =
+    ///   member #c$.Method () = ()
+    [<Test>]
+    member public this.``GotoDefinition.ObjectOriented.ThisDef`` () =
+      this.GotoDefinitionTestWithSimpleFile ".Method () = () (*loc-63*)" (Some("member c.Method () = () (*loc-63*)", "c"))
+
+    /// type Class () =
+    ///   static member #Foo$ () = ()
+    [<Test>]
+    member public this.``GotoDefinition.ObjectOriented.StaticMethodDef`` () =
+      this.GotoDefinitionTestWithSimpleFile " () = () (*loc-64*)" (Some("static member Foo () = () (*loc-64*)", "Foo"))
+
+    /// type #Class () =
+    ///   member Method () = ()
+    /// let c = Class$ ()
+    [<Test>]
+    member public this.``GotoDefinition.ObjectOriented.ConstructorUse`` () =
+      this.GotoDefinitionTestWithSimpleFile " () (*loc-65*)" (Some("type Class () = (*loc-62*)", "Class"))
+
+    /// type Class () =
+    ///   member #Method () = ()
+    /// let c = Class ()
+    /// c.Method$ ()
+    [<Test>]
+    member public this.``GotoDefinition.ObjectOriented.MethodInvocation`` () =
+      this.GotoDefinitionTestWithSimpleFile " () (*loc-66*)" (Some("member c.Method () = () (*loc-63*)", "c.Method"))
+
+    /// type Class () =
+    ///   static member #Foo () = ()
+    /// Class.Foo$ ()
+    [<Test>]
+    member public this.``GotoDefinition.ObjectOriented.StaticMethodInvocation`` () =
+      this.GotoDefinitionTestWithSimpleFile " () (*loc-67*)" (Some("static member Foo () = () (*loc-64*)", "Foo"))
+
+    /// type Class () =
+    ///   member c.Method# () = c.Method$ ()
+    [<Test>]
+    member public this.``GotoDefinition.ObjectOriented.MethodSelfInvocation`` () =
+      this.GotoDefinitionTestWithSimpleFile " () (*loc-68*)" (Some("member c.Method  () = c.Method () (*loc-68*)", "c.Method"))
+
+    /// type Class () =
+    ///   member c.Method1 ()  = c.Method2$ ()
+    ///   member #c.Method2 () = c.Method1 ()
+    [<Test>]
+    member public this.``GotoDefinition.ObjectOriented.MethodToMethodForward`` () =
+      this.GotoDefinitionTestWithSimpleFile " () (*loc-69*)" (Some("member c.Method2 () = c.Method1 () (*loc-70*)", "c.Method2"))
+
+    /// type Class () =
+    ///   member c.Method () = ()
+    /// type Class' () =
+    ///   member c.Method () =
+    ///     let #c = Class ()
+    ///     c$.Method ()
+    [<Test>]
+    member public this.``GotoDefinition.ObjectOriented.ShadowThis`` () =
+      this.GotoDefinitionTestWithSimpleFile ".Method () (*loc-71*)" (Some("let c = Class ()", "c"))
+
+    /// type Class () =
+    ///   member #c.Method () = ()
+    /// type Class' () =
+    ///   member c.Method () =
+    ///     let c = Class ()
+    ///     c.Method$ ()
+    [<Test>]
+    member public this.``GotoDefinition.ObjectOriented.ShadowThisMethodInvocation`` () =
+      this.GotoDefinitionTestWithSimpleFile " () (*loc-71*)" (Some("member c.Method () = () (*loc-63*)", "c.Method"))
+
+    [<Test>]
+    member this.``GotoDefinition.ObjectOriented.StructConstructor`` () =
+      let lines = 
+        [ "#light"
+          "[<Struct>]"
+          "type Astruct ="
+          "  val a : int"
+          "  new(a) = { a = a }" 
+          "let a = Astruct(0)"
+        ]
+      
+      let (_,_, file) = this.CreateSingleFileProject(lines)
+
+      MoveCursorToStartOfMarker (file, "Astruct(0)")
+      let res = GotoDefinitionAtCursor file |> fun x -> x.ToOption() |>  Option.map (fun (res, _) -> res.iStartLine + 1, res.iStartIndex + 1)
+      AssertEqual(Some(5, 3), res)
+
+    // ********** GetCompleteIdentifierIsland tests **********
+
+    /// takes a string with a `$` representing the cursor position, gets the
+    /// GotoDefinition identifier at that position and compares against expected
+    /// result
+
+    member this.GetCompleteIdTest tolerate (s : string)(exp : string option) : unit =
+      let n = s.IndexOf '$'
+      let s = s.Remove (n, 1)
+      match (Microsoft.VisualStudio.FSharp.LanguageService.QuickParse.GetCompleteIdentifierIsland tolerate s n, exp) with
+      | (Some (s1, _, _), Some s2) -> 
+        printfn "%s" "Received result, as expected."
+        Assert.AreEqual (s1, s2)
+      | (None,         None)    -> 
+        printfn "%s" "Received no result, as expected."
+      | (Some _,       None)    -> 
+        Assert.Fail("Received result, but none was expected!")
+      | (None,         Some _)  -> 
+        Assert.Fail("Expected result, but didn't receive one!")
+
+    [<Test>]
+    [<Category("PerfCheck")>]
+    member public this.``GetCompleteIdTest.TrivialBefore`` () =
+      for tolerate in [true;false] do
+          this.GetCompleteIdTest tolerate "let $ThisIsAnIdentifier = ()" (Some "ThisIsAnIdentifier")
+
+    [<Test>]
+    member public this.``GetCompleteIdTest.TrivialMiddle`` () =
+      for tolerate in [true;false] do
+          this.GetCompleteIdTest tolerate "let This$IsAnIdentifier = ()" (Some "ThisIsAnIdentifier")
+
+    [<Test>]
+    member public this.``GetCompleteIdTest.TrivialEnd`` () =
+      this.GetCompleteIdTest true "let ThisIsAnIdentifier$ = ()" (Some "ThisIsAnIdentifier")
+      this.GetCompleteIdTest false "let ThisIsAnIdentifier$ = ()" None
+
+    [<Test>]
+    member public this.``GetCompleteIdTest.GetsUpToDot1`` () =
+      for tolerate in [true;false] do
+          this.GetCompleteIdTest tolerate "let ThisIsAnIdentifier = Te$st.Moo.Foo.bar" (Some "Test")
+
+    [<Test>]
+    member public this.``GetCompleteIdTest.GetsUpToDot2`` () =
+      for tolerate in [true;false] do
+          this.GetCompleteIdTest tolerate "let ThisIsAnIdentifier = Test.Mo$o.Foo.bar" (Some "Test.Moo")
+
+    [<Test>]
+    member public this.``GetCompleteIdTest.GetsUpToDot3`` () =
+      for tolerate in [true;false] do
+          this.GetCompleteIdTest tolerate "let ThisIsAnIdentifier = Test.Moo.Fo$o.bar" (Some "Test.Moo.Foo")
+
+    [<Test>]
+    member public this.``GetCompleteIdTest.GetsUpToDot4`` () =
+      for tolerate in [true;false] do
+          this.GetCompleteIdTest tolerate "let ThisIsAnIdentifier = Test.Moo.Foo.ba$r" (Some "Test.Moo.Foo.bar")
+
+    [<Test>]
+    member public this.``GetCompleteIdTest.GetsUpToDot5`` () =
+      this.GetCompleteIdTest true "let ThisIsAnIdentifier = Test.Moo.Foo.bar$" (Some "Test.Moo.Foo.bar")
+      this.GetCompleteIdTest false "let ThisIsAnIdentifier = Test.Moo.Foo.bar$" None
+
+    [<Test>]
+    member public this.``GetCompleteIdTest.GetOperator`` () =
+      for tolerate in [true;false] do
+          this.GetCompleteIdTest tolerate "let ThisIsAnIdentifier = 3 +$ 4" None
+
+
+    [<Test>]
+    member public this.``Identifier.IsConstructor.Bug2516``() =
+        let fileContents = """
+            module GotoDefinition
+            type One(*Mark1*) = One
+            let f (x : One(*Mark2*)) = 2"""
+        let definitionCode = "type One(*Mark1*) = One"
+        this.VerifyGoToDefnSuccessAtStartOfMarker(fileContents,"(*Mark1*)",definitionCode) 
+        
+    [<Test>]
+    member public this.``Identifier.IsTypeName.Bug2516``() =
+        let fileContents = """
+            module GotoDefinition
+            type One(*Mark1*) = One
+            let f (x : One(*Mark2*)) = 2"""
+        let definitionCode = "type One(*Mark1*) = One"
+        this.VerifyGoToDefnSuccessAtStartOfMarker(fileContents,"(*Mark2*)",definitionCode)       
+       
+    [<Test>]
+    member public this.``ModuleName.OnDefinitionSite.Bug2517``() =
+        let fileContents = """
+            namespace GotoDefinition
+            module Foo(*Mark*) =
+            let x = ()"""
+        let definitionCode = "module Foo(*Mark*) ="
+        this.VerifyGoToDefnSuccessAtStartOfMarker(fileContents,"(*Mark*)",definitionCode) 
+
+    [<Test>]
+    /// GotoDef on abbreviation
+    member public this.``GotoDefinition.Abbreviation.Bug193064``() =
+        let fileContents = """
+            type X = int
+            let f (x:X) = x(*Marker*) """
+        let definitionCode = "let f (x:X) = x(*Marker*)"
+        this.VerifyGoToDefnSuccessAtStartOfMarker(fileContents,"x(*Marker*)",definitionCode) 
+
+    [<Test>]
+    /// Verify the GotoDefinition on UoM yield does NOT jump out error dialog, 
+    /// will do nothing in automation lab machine or GTD SI.fs on dev machine with enlistment.
+    member public this.``GotoDefinition.UnitOfMeasure.Bug193064``() =
+        let fileContents = """
+            open Microsoft.FSharp.Data.UnitSystems.SI
+            UnitSymbols.A(*Marker*)"""
+        this.VerifyGoToDefnNoErrorDialogAtStartOfMarker(fileContents,"A(*Marker*)", "type A = ampere")
+
+
+// Allow languageService tests to run under different contextes
+namespace UnitTests.Tests.LanguageService.GotoDefinition
+open UnitTests.Tests.LanguageService
+open UnitTests.TestLib.LanguageService
+open UnitTests.TestLib.ProjectSystem
+open NUnit.Framework
+open Salsa.Salsa
+
+// context msbuild
+[<TestFixture>] 
+[<Category("LanguageService.MSBuild")>]
+type ``MSBuild`` = 
+   inherit GotoDefinitionTests
+   new() = { inherit GotoDefinitionTests(VsOpts = fst (Models.MSBuild())); }
+
+// Context project system
+[<TestFixture>]
+[<Category("LanguageService.ProjectSystem")>]
+type ``ProjectSystem`` = 
+    inherit GotoDefinitionTests
+    new() = { inherit GotoDefinitionTests(VsOpts = LanguageServiceExtension.ProjectSystem); }  
diff --git a/vsintegration/src/unittests/Tests.LanguageService.IncrementalBuild.fs b/vsintegration/src/unittests/Tests.LanguageService.IncrementalBuild.fs
new file mode 100644
index 0000000..ed85fa3
--- /dev/null
+++ b/vsintegration/src/unittests/Tests.LanguageService.IncrementalBuild.fs
@@ -0,0 +1,580 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+namespace UnitTests.Tests.LanguageService
+
+open System
+open System.IO
+open NUnit.Framework
+open Salsa.Salsa
+open Salsa.VsOpsUtils               
+open Microsoft.FSharp.Compiler
+open Microsoft.FSharp.Compiler.AbstractIL.Internal.Library
+open IncrementalBuild
+    
+/// Useful methods that someday might go into IncrementalBuild
+module internal Vector = 
+    /// Convert from vector to a scalar
+    let ToScalar<'I> (taskname:string) (input:Vector<'I>) : Scalar<'I array> =
+        let Identity inArray = inArray
+        Vector.Demultiplex taskname Identity input
+            
+    
+[<TestFixture>] 
+[<Category("LanguageService.MSBuild")>]
+[<Category("LanguageService.ProjectSystem")>]
+type IncrementalBuild() = 
+    
+    
+    /// Called per test
+    [<SetUp>]
+    member this.Setup() =
+        //Trace.Log <- "IncrementalBuild"
+        ()
+
+
+    // This test is related to 
+    //    835552  Language service loses track of files in project due to intermitent file read failures
+    // It verifies that incremental builder can handle changes to timestamps that happen _before_ the
+    // stamp function exists. This ensures there's not a race in the data gathered for tracking file
+    // timestamps in parsing.
+    [<Test>]
+    member public rb.StampUpdate() =
+        let path = Path.GetTempFileName()
+
+        let TouchFile() =
+            printfn "Touching file"
+            File.WriteAllText(path,"Some text")
+
+        let updateStamp = ref true
+
+        let StampFile filename =
+            let result = File.GetLastWriteTime(filename)
+            if !updateStamp then
+                // Here, simulate that VS is writing to our file.
+                TouchFile()
+            result
+
+        let Map filename = 
+            "map:"+filename
+
+        let build = new BuildDescriptionScope()
+        let input = InputVector<string> "InputVector"
+        let stamped = Vector.Stamp "Stamp" StampFile input
+        let mapped = Vector.Map "Map" Map stamped
+        build.DeclareVectorOutput("Mapped", mapped)
+        let build = build.GetInitialPartialBuild(["InputVector",1,[box path]],[])
+
+        let DoCertainStep build = 
+            match IncrementalBuild.Step "Mapped" build with
+            | Some(build) -> build
+            | None -> failwith "Expected to be able to step"
+
+        // While updateStamp is true we should be able to step as continuously
+        // because there will always be more to build.
+        let mutable build = build
+        for i in 0..5 do 
+            printfn "Iteration %d" i
+            build <- DoCertainStep build
+            System.Threading.Thread.Sleep 2000
+
+        // Now, turn off updateStamp and the build should just finish.
+        updateStamp:=false
+        build <- DoCertainStep build
+        build <- DoCertainStep build
+        match IncrementalBuild.Step "Mapped" build with
+        | Some(build) -> failwith "Build should have stopped"
+        | None -> () 
+
+            
+    /// Test that stamp works
+    [<Test>]
+    member public rb.StampScan() =
+        
+        let mapSuffix = ref "Suffix1"
+        let Scan acc filename = 
+            eventually { return acc+"-"+filename+"-"+(!mapSuffix) }
+            
+        let stampAs = ref DateTime.Now
+        let StampFile(filename) = 
+            !stampAs
+                            
+        let build = new BuildDescriptionScope()
+        let input = InputVector<string> "InputVector"
+        let acc = InputScalar<string> "Accumulator"
+        let stamped = Vector.Stamp "Stamp" StampFile input
+        let scanned = Vector.ScanLeft "Scan" Scan acc stamped
+        build.DeclareVectorOutput("Scanned", scanned)
+        let build = build.GetInitialPartialBuild(["InputVector",3,[box "File1.fs";box "File2.fs";box "File3.fs"]],["Accumulator",box "AccVal"])
+            
+        printf "-[Step1]----------------------------------------------------------------------------------------\n"
+        // Evaluate the first time.
+        let build = Eval "Scanned" build
+        let r = GetVectorResult<string>("Scanned",build)
+        Assert.AreEqual("AccVal-File1.fs-Suffix1-File2.fs-Suffix1",r.[1])
+            
+        printf "-[Step2]----------------------------------------------------------------------------------------\n"
+        // Evaluate the second time. No change should be seen.
+        mapSuffix:="Suffix2"
+        let build = Eval "Scanned" build
+        let r = GetVectorResult<string>("Scanned",build)
+        Assert.AreEqual("AccVal-File1.fs-Suffix1-File2.fs-Suffix1",r.[1])
+
+        printf "-[Step3]----------------------------------------------------------------------------------------\n"
+        // Evaluate a third time with timestamps updated. Should cause a rebuild
+        System.Threading.Thread.Sleep 10 // Sleep a little to avoid grabbing the same 'Now'
+        stampAs:=DateTime.Now
+        let build = Eval "Scanned" build
+        let r = GetVectorResult<string>("Scanned",build)
+        Assert.AreEqual("AccVal-File1.fs-Suffix2-File2.fs-Suffix2",r.[1])
+             
+            
+    /// Test case of zero elements in a vector
+    [<Test>]
+    member public rb.aaZeroElementVector() = // Starts with 'aa' to put it at the front.
+        let stamp = ref DateTime.Now
+        let Mult(i:int) : string array = Array.create i ""
+        let Stamp(s:string) = !stamp
+        let Map(s:string) = s
+        let Demult(a:string array) : int = a.Length
+            
+        let build = new BuildDescriptionScope()
+        let input = InputScalar<int> "InputScalar"
+        let multiplexed = Scalar.Multiplex "Mult" Mult input
+        let stamped = Vector.Stamp "Stamp" Stamp multiplexed
+        let mapped = Vector.Map "Map" Map stamped
+        let demultiplexed = Vector.Demultiplex "Demult" Demult mapped
+        build.DeclareVectorOutput("Multiplexed", multiplexed)
+        build.DeclareVectorOutput("Stamped", stamped)
+        build.DeclareVectorOutput("Mapped", mapped)
+        build.DeclareScalarOutput("Result", demultiplexed)
+            
+        // Try first with one input
+        let build1 = build.GetInitialPartialBuild([],["InputScalar", box 1])    
+        let build1Evaled = Eval "Result" build1
+        let r1 = GetScalarResult<int>("Result",build1Evaled)
+        match r1 with
+        | Some(v,dt) -> Assert.AreEqual(1,v) 
+        | None -> failwith "Expected the value 1 to be returned."
+            
+        // Now with zero. This was the original bug.
+        stamp := DateTime.Now
+        let build0 = build.GetInitialPartialBuild([],["InputScalar", box 0])            
+        let build0Evaled = Eval "Result" build0
+        let r0 = GetScalarResult<int>("Result",build0Evaled)
+        match r0 with
+        | Some(v,dt) -> Assert.AreEqual(0,v) 
+        | None -> failwith "Expected the value 0 to be returned."  
+        ()
+         
+            
+    /// Here, we want a multiplex to increase the number of items processed.
+    [<Test>]
+    member public rb.MultiplexTransitionUp() =
+        let elements = ref 1
+        let timestamp = ref System.DateTime.Now
+        let Mult(s:string) : string array =  [| for i in 1..!elements -> sprintf "Element %d" i |]
+        let Stamp(s) = !timestamp
+        let Map(s:string) = sprintf "Mapped %s " s
+        let Demult(a:string array) : string = "Demult"
+        let Result(a:string array) : string = String.Join(",", a)
+        let now = System.DateTime.Now
+        let FixedTimestamp _  =  now
+            
+        let build = new BuildDescriptionScope()
+        let input = InputVector<string> "InputVector"
+        let stampedInput = Vector.Stamp "StampInput" Stamp input
+        let demultiplexedInput = Vector.Demultiplex "DemultInput" Demult stampedInput
+        let multiplexed = Scalar.Multiplex "Mult" Mult demultiplexedInput
+        let mapped = Vector.Map "Map" Map multiplexed
+        let mapped = Vector.Stamp "FixedTime" FixedTimestamp mapped // Change in vector size should x-ray through even if timestamps haven't changed in remaining items.
+        let demultiplexed = Vector.Demultiplex "DemultResult" Result mapped
+        build.DeclareScalarOutput("Result", demultiplexed)
+            
+        // Create the build.
+        let build = build.GetInitialPartialBuild(["InputVector",1,[box "Input 0"]],[])         
+            
+        // Evaluate it with value 1
+        elements := 1
+        let build = Eval "Result" build
+        let r1 = GetScalarResult<string>("Result", build)
+        match r1 with
+        | Some(s,dt) -> printfn "%s" s
+        | None -> failwith ""
+            
+        // Now, re-evaluate it with value 2
+        elements := 2
+        System.Threading.Thread.Sleep(100)
+        timestamp := System.DateTime.Now
+            
+            
+            
+        let build = Eval "Result" build
+        let r2 = GetScalarResult<string>("Result", build)
+        match r2 with
+        | Some(s,dt) -> Assert.AreEqual("Mapped Element 1 ,Mapped Element 2 ",s)
+        | None -> failwith ""
+            
+    /// Here, we want a multiplex to decrease the number of items processed.
+    [<Test>]
+    member public rb.MultiplexTransitionDown() =
+        let elements = ref 1
+        let timestamp = ref System.DateTime.Now
+        let Mult(s:string) : string array =  [| for i in 1..!elements -> sprintf "Element %d" i |]
+        let Stamp(s) = !timestamp
+        let Map(s:string) = 
+            printfn "Map called with %s" s
+            sprintf "Mapped %s " s
+        let Demult(a:string array) : string = 
+            printfn "Demult called with %d items" a.Length
+            sprintf "Demult %s" (String.Join(",",a))
+        let Result(a:string array) : string = 
+            let result = String.Join(",", a)
+            printfn "Result called with %d items returns %s" a.Length result
+            result
+        let now = System.DateTime.Now
+        let FixedTimestamp _  =  
+            printfn "Fixing timestamp"
+            now               
+            
+        let build = new BuildDescriptionScope()
+        let input = InputVector<string> "InputVector"
+        let stampedInput = Vector.Stamp "StampInput" Stamp input
+        let demultiplexedInput = Vector.Demultiplex "DemultInput" Demult stampedInput
+        let multiplexed = Scalar.Multiplex "Mult" Mult demultiplexedInput
+        let mapped = Vector.Map "Map" Map multiplexed
+        let fixedmapped = Vector.Stamp "FixedTime" FixedTimestamp mapped // Change in vector size should x-ray through even if timestamps haven't changed in remaining items.
+        let demultiplexed = Vector.Demultiplex "DemultResult" Result fixedmapped
+            
+        build.DeclareScalarOutput("DemultiplexedInput", demultiplexedInput)
+        build.DeclareVectorOutput("Mapped", mapped)
+        build.DeclareVectorOutput("FixedMapped", fixedmapped)            
+        build.DeclareScalarOutput("Result", demultiplexed)
+            
+        // Create the build.
+        let build = build.GetInitialPartialBuild(["InputVector",1,[box "Input 0"]],[])         
+            
+        // Evaluate it with value 2
+        elements := 2
+        let build = Eval "Result" build
+        let r1 = GetScalarResult<string>("Result", build)
+        match r1 with
+        | Some(s,dt) -> printfn "%s" s
+        | None -> failwith ""
+            
+        // Now, re-evaluate it with value 1
+        elements := 1
+        System.Threading.Thread.Sleep(100)
+        timestamp := System.DateTime.Now
+            
+        let buildDemuxed = Eval "DemultiplexedInput" build
+        let rdm = GetScalarResult<string>("DemultiplexedInput",buildDemuxed)
+        match rdm with
+        | Some(s,dt)->Assert.AreEqual("Demult Input 0", s)
+        | None -> failwith "unexpected"
+            
+        let buildMapped = Eval "Mapped" build
+        let mp = GetVectorResult<string>("Mapped",buildMapped)
+        Assert.AreEqual(1,mp.Length)
+        let melem = mp.[0]
+        Assert.AreEqual("Mapped Element 1 ", melem)
+            
+        let buildFixedMapped = Eval "FixedMapped" buildMapped
+        let mp = GetVectorResult<string>("FixedMapped",buildFixedMapped)
+        Assert.AreEqual(1,mp.Length)
+        let melem = mp.[0]
+        Assert.AreEqual("Mapped Element 1 ", melem)            
+            
+        let build = Eval "Result" build
+        let r2 = GetScalarResult<string>("Result", build)
+        match r2 with
+        | Some(s,dt) -> Assert.AreEqual("Mapped Element 1 ",s)
+        | None -> failwith "unexpected"
+            
+    /// Test that stamp works
+    [<Test>]
+    member public rb.StampMap() =
+        
+        let mapSuffix = ref "Suffix1"
+        let MapIt(filename) = 
+            filename+"."+(!mapSuffix)
+            
+        let stampAs = ref DateTime.Now
+        let StampFile(filename) =  
+            !stampAs
+                            
+        let build = new BuildDescriptionScope()
+        let input = InputVector<string> "InputVector"
+        let stamped = Vector.Stamp "Stamp" StampFile input
+        let mapped = Vector.Map "Map" MapIt stamped
+        build.DeclareVectorOutput("Mapped", mapped)
+        let build = build.GetInitialPartialBuild(["InputVector",3,[box "File1.fs";box "File2.fs";box "File3.fs"]],[])
+            
+        printf "-[Step1]----------------------------------------------------------------------------------------\n"
+        // Evaluate the first time.
+        let build = Eval "Mapped" build
+        let r = GetVectorResult<string>("Mapped",build)
+        Assert.AreEqual("File2.fs.Suffix1",r.[1])
+            
+        printf "-[Step2]----------------------------------------------------------------------------------------\n"
+        // Evaluate the second time. No change should be seen.
+        mapSuffix:="Suffix2"
+        let build = Eval "Mapped" build
+        let r = GetVectorResult<string>("Mapped",build)
+        Assert.AreEqual("File2.fs.Suffix1",r.[1])
+
+        printf "-[Step3]----------------------------------------------------------------------------------------\n"
+        // Evaluate a third time with timestamps updated. Should cause a rebuild
+        while !stampAs = DateTime.Now do 
+            System.Threading.Thread.Sleep 10 // Sleep a little to avoid grabbing the same 'Now'
+        stampAs:=DateTime.Now
+        let build = Eval "Mapped" build
+        let r = GetVectorResult<string>("Mapped",build)
+        Assert.AreEqual("File2.fs.Suffix2",r.[1])
+            
+    /// Test that stamp works
+    [<Test>]
+    member public rb.StampDemultiplex() =
+        
+        let joinedResult = ref "Join1"
+        let Join(filenames:_[]) = 
+            !joinedResult
+            
+        let stampAs = ref DateTime.Now
+        let StampFile(filename) = 
+            !stampAs
+                            
+        let build = new BuildDescriptionScope()
+        let input = InputVector<string> "InputVector"
+        let stamped = Vector.Stamp "Stamp" StampFile input
+        let joined = Vector.Demultiplex "Demultiplex" Join stamped
+        build.DeclareScalarOutput("Joined", joined)
+        let build = build.GetInitialPartialBuild(["InputVector",3,[box "File1.fs";box "File2.fs";box "File3.fs"]],[])
+            
+        printf "-[Step1]----------------------------------------------------------------------------------------\n"
+        // Evaluate the first time.
+        let build = Eval "Joined" build
+        let (r,_) = Option.get (GetScalarResult<string>("Joined",build))
+        Assert.AreEqual("Join1",r)
+            
+        printf "-[Step2]----------------------------------------------------------------------------------------\n"
+        // Evaluate the second time. No change should be seen.
+        joinedResult:="Join2"
+        let build = Eval "Joined" build
+        let (r,_) = Option.get (GetScalarResult<string>("Joined",build))
+        Assert.AreEqual("Join1",r)
+
+        printf "-[Step3]----------------------------------------------------------------------------------------\n"
+        // Evaluate a third time with timestamps updated. Should cause a rebuild
+        while !stampAs = DateTime.Now do 
+            System.Threading.Thread.Sleep 10 // Sleep a little to avoid grabbing the same 'Now'
+        stampAs:=DateTime.Now
+        let build = Eval "Joined" build
+        let (r,_) = Option.get (GetScalarResult<string>("Joined",build))
+        Assert.AreEqual("Join2",r)
+            
+
+    /// Test that Demultiplex followed by ScanLeft works
+    [<Test>]
+    member public rb.DemultiplexScanLeft() =
+        let Size(ar:_[]) = ar.Length
+        let Scan acc (file :string) = eventually { return acc + file.Length }
+        let build = new BuildDescriptionScope()
+        let inVector = InputVector<string> "InputVector"
+        let vectorSize = Vector.Demultiplex "Demultiplex" Size inVector
+        let scanned = Vector.ScanLeft "Scan" Scan vectorSize inVector
+        build.DeclareScalarOutput("Size", vectorSize)
+        build.DeclareVectorOutput("Scanned", scanned)
+        let build = build.GetInitialPartialBuild(["InputVector",3,[box "File1.fs";box "File2.fs";box "File3.fs"]],[])
+            
+        let e = Eval "Scanned" build   
+        let r = GetScalarResult<int>("Size",e)  
+        match r with 
+        | Some(r,_)->Assert.AreEqual(3,r)
+        | None -> Assert.Fail("No size was returned")       
+            
+            
+    /// Test that Scalar.Multiplex works.
+    [<Test>] 
+    member public rb.ScalarMultiplex() =
+        let MultiplexScalar inp = [|inp+":1";inp+":2";inp+":3"|]
+        
+        let build = new BuildDescriptionScope()
+        let inScalar = InputScalar<string> "Scalar"
+        let multiplexed = Scalar.Multiplex "MultiplexScalar" MultiplexScalar inScalar
+        build.DeclareVectorOutput("Output", multiplexed)
+            
+        let b = build.GetInitialPartialBuild([],["Scalar",box "A Scalar Value"])
+        let e = Eval "Output" b
+        let r = GetVectorResult("Output",e)
+        Assert.AreEqual("A Scalar Value:2", r.[1])
+            
+    /// Test that Scalar.Map works.
+    [<Test>] 
+    member public rb.ScalarMap() =
+        let MapScalar inp = "out:"+inp
+        
+        let build = new BuildDescriptionScope()
+        let inScalar = InputScalar<string> "Scalar"
+        let mappedScalar = Scalar.Map "MapScalar" MapScalar inScalar
+        build.DeclareScalarOutput("Output", mappedScalar)
+            
+        let b = build.GetInitialPartialBuild([],["Scalar",box "A Scalar Value"])
+        let e = Eval "Output" b
+        let r = GetScalarResult("Output",e)
+        match r with 
+            | Some(r,_) -> Assert.AreEqual("out:A Scalar Value", r)
+            | None -> Assert.Fail()                 
+    
+    /// Test that a simple scalar action works.
+    [<Test>] 
+    member public rb.Scalar() =
+        let build = new BuildDescriptionScope()
+        let inScalar = InputScalar<string> "Scalar"
+        build.DeclareScalarOutput("Output", inScalar)
+        let b = build.GetInitialPartialBuild([],["Scalar",box "A Scalar Value"])
+        let e = Eval "Output" b
+        let r = GetScalarResult("Output",e)
+        match r with 
+            | Some(r,_) -> Assert.AreEqual("A Scalar Value", r)
+            | None -> Assert.Fail()
+            
+    /// Test that ScanLeft works.
+    [<Test>]
+    member public rb.ScanLeft() =
+        let DoIt (a:int*string) (b:string) =
+            eventually { return ((fst a)+1,b) }
+            
+        let build = new BuildDescriptionScope()
+        let inScalar = InputScalar<int*string> "InputScalar"
+        let inVector = InputVector<string> "InputVector"
+        let scanned = Vector.ScanLeft "DoIt" DoIt inScalar inVector
+        build.DeclareVectorOutput("Output", scanned)
+            
+        let build = build.GetInitialPartialBuild(["InputVector",3,[box "File1.fs";box "File2.fs";box "File3.fs"]],["InputScalar",box (5,"")])
+        let e = Eval "Output" build
+        let r = GetVectorResult("Output",e)
+        if [| (6,"File1.fs"); (7,"File2.fs"); (8, "File3.fs") |] <> r then 
+            printfn "Got %A" r
+            Assert.Fail()
+        ()     
+            
+    /// Convert a vector to a scalar
+    [<Test>]
+    member public rb.ToScalar() =
+        let build = new BuildDescriptionScope()
+        let inVector = InputVector<string> "InputVector"
+        let asScalar = Vector.ToScalar "ToScalar" inVector
+        build.DeclareScalarOutput("Output", asScalar)
+        let build = build.GetInitialPartialBuild(["InputVector",3,[box "File1.fs";box "File2.fs";box "File3.fs"]],[])
+        let e = Eval "Output" build
+        let r = GetScalarResult<string array>("Output",e)
+        match r with 
+        | Some(r,ts)->
+            if "File3.fs"<>(r.[2]) then
+                printf "Got %A\n" (r.[2])
+                Assert.Fail()
+        | None -> Assert.Fail()
+
+             
+            
+    /// This test replicates the data flow of the assembly reference model. It includes several concepts 
+    /// that were new at the time: Scalars, Invalidation, Disposal
+    [<Test>]
+    member public rb.AssemblyReferenceModel() =
+        let Parse(filename) = sprintf "Parse(%s)" filename
+        let ApplyMetaCommands(parseResults:string[]) = "tcConfig-of("+String.Join(",",parseResults)+")"
+        let GetReferencedAssemblyNames(tcConfig) = [|"Assembly1.dll";"Assembly2.dll";"Assembly3.dll"|]
+        let ReadAssembly(assemblyName) = sprintf "tcImport-of(%s)" assemblyName
+        let CombineImports(imports) = "tcAcc"
+        let TypeCheck tcAcc parseResults = eventually { return tcAcc }
+
+        // Build rules.
+        let build = new BuildDescriptionScope()
+        let filenames = InputVector<string> "Filenames"
+        let parseTrees = Vector.Map "Parse" Parse filenames
+        let parseTreesAsScalar = Vector.ToScalar<string> "ScalarizeParseTrees" parseTrees
+        let tcConfig = Scalar.Map "ApplyMetaCommands" ApplyMetaCommands parseTreesAsScalar
+        let referencedAssemblyNames = Scalar.Multiplex "GetReferencedAssemblyNames" GetReferencedAssemblyNames tcConfig
+        let readAssemblies = Vector.Map "ReadAssembly" ReadAssembly referencedAssemblyNames
+        let tcAcc = Vector.Demultiplex "CombineImports" CombineImports readAssemblies
+        let tcResults = Vector.ScanLeft "TypeCheck" TypeCheck tcAcc parseTrees
+        build.DeclareVectorOutput("TypeCheckingStates",tcResults)
+            
+        let build = build.GetInitialPartialBuild(["Filenames",3,[box "File1.fs";box "File2.fs";box "File3.fs"]],[])
+        let e = Eval "TypeCheckingStates" build
+        let r = GetVectorResult("TypeCheckingStates",e)
+            
+        ()
+        
+    [<Test;ExpectedException(typeof<Exception>)>]
+    member public rb.DuplicateExpressionNamesNotAllowed() =
+            let DoIt s = s
+            let b = 
+                let build = new BuildDescriptionScope()
+                let i = InputVector<string> "Input"
+                let r = Vector.Map "Input" DoIt i
+                build.DeclareVectorOutput("Output",r)
+                build.GetInitialPartialBuild(["Input",1,[box ""]],[])
+                            
+            let e = Eval "Output" b
+            ()               
+
+    [<Test>]
+    member public rb.OneToOneWorks() =
+        let VectorModify (input:int) : string =
+            sprintf "Transformation of %d" input
+
+        let bound = 
+            let build = new BuildDescriptionScope()
+            let inputs = InputVector<int> "Inputs"
+            let outputs = Vector.Map "Modify" VectorModify inputs
+            build.DeclareVectorOutput("Outputs",outputs)
+            build.GetInitialPartialBuild(["Inputs",4,[box 1;box 2;box 3;box 4]],[])
+
+        let evaled = bound |> Eval "Outputs" 
+        let outputs = GetVectorResult("Outputs",evaled)
+        Assert.AreEqual("Transformation of 4", outputs.[3])
+        ()   
+            
+    /// In this bug, the desired output is between other outputs.
+    /// The getExprById function couldn't find it.            
+    [<Test>]
+    member public rb.HiddenOutputGroup() =
+        let VectorModify (input:int) : string =
+            sprintf "Transformation of %d" input
+
+        let bound = 
+            let build = new BuildDescriptionScope()
+            let inputs = InputVector<int> "Inputs"
+            let outputs = Vector.Map "Modify" VectorModify inputs
+            build.DeclareVectorOutput("Inputs1", inputs)
+            build.DeclareVectorOutput("Inputs2", inputs)
+            build.DeclareVectorOutput("Inputs3", inputs)
+            build.DeclareVectorOutput("Outputs", outputs)
+            build.DeclareVectorOutput("Inputs4", inputs)
+            build.DeclareVectorOutput("Inputs5", inputs)
+            build.DeclareVectorOutput("Inputs6", inputs)
+            build.GetInitialPartialBuild(["Inputs",4,[box 1;box 2;box 3;box 4]],[])
+
+        let evaled = bound |> Eval "Outputs" 
+        let outputs = GetVectorResult("Outputs",evaled)
+        Assert.AreEqual("Transformation of 4", outputs.[3])
+        ()               
+            
+    /// Empty build should just be a NOP.
+    [<Test>]
+    member public rb.EmptyBuildIsNop() =
+        let VectorModify (input:int) : string =
+            sprintf "Transformation of %d" input
+
+        let bound = 
+            let build = new BuildDescriptionScope()
+            let inputs = InputVector<int> "Inputs"
+            let outputs = Vector.Map "Modify" VectorModify inputs
+            build.DeclareVectorOutput("Outputs", outputs)
+            build.GetInitialPartialBuild(["Inputs",0,[]],[])
+
+        let evaled = bound |> Eval "Outputs" 
+        let outputs = GetVectorResult("Outputs",evaled)
+        ()               
+              
diff --git a/vsintegration/src/unittests/Tests.LanguageService.NavigationBar.fs b/vsintegration/src/unittests/Tests.LanguageService.NavigationBar.fs
new file mode 100644
index 0000000..f58510d
--- /dev/null
+++ b/vsintegration/src/unittests/Tests.LanguageService.NavigationBar.fs
@@ -0,0 +1,239 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+namespace UnitTests.Tests.LanguageService
+
+open System
+open NUnit.Framework
+open Salsa.Salsa
+open Salsa.VsOpsUtils
+open UnitTests.TestLib.Salsa
+open UnitTests.TestLib.Utils
+open UnitTests.TestLib.LanguageService
+
+type NavigationBarTests() =
+    inherit LanguageServiceBaseTests()
+
+    (* Unit tests for collapse region & navigation bar ------------------------------------- *)
+    
+    member private this.TestNavigationBar (file : string list) findDecl expectedMembers =
+        
+        let (_, _, file) = this.CreateSingleFileProject(file)
+
+        // Verify that the types&modules list contains 'findDecl'
+        let navigation = GetNavigationContentAtCursor(file)
+        AssertNavigationContains(navigation.TypesAndModules, findDecl)
+        let idxDecl = navigation.TypesAndModules |> Array.findIndex (fun nav -> nav.Label = findDecl)
+        let decl = navigation.TypesAndModules.[idxDecl]
+        
+        // Navigate to the definition and get the contents again
+        MoveCursorTo(file, decl.Span.iStartLine + 1, decl.Span.iStartIndex) // line index is in the 0-based form
+        let navigation = GetNavigationContentAtCursor(file)
+        // Ensure that the right thing is selected in the dropdown
+        AssertEqual(idxDecl, navigation.SelectedType)
+        // Ensure that member list contains expected members
+        AssertNavigationContainsAll(navigation.Members, expectedMembers)
+        
+        // Find member declaration, go to the location & test the identifier island
+        for memb in expectedMembers do
+            let decl = navigation.Members |> Array.find (fun nav -> nav.Label = memb)
+            MoveCursorTo(file, decl.Span.iStartLine + 1, decl.Span.iStartIndex + 1)
+            match GetIdentifierAtCursor file with
+            | None -> 
+                Assert.Fail("No identifier at cursor!")
+            | Some (id, _) -> 
+                if not (id.Contains(memb)) then Assert.Fail(sprintf "Found '%s' which isn't substring of the expected '%s'." id memb)
+               
+    member private this.TestHiddenRegions (file : list<string>) regionMarkers =        
+        let (_, _, file) = this.CreateSingleFileProject(file)
+
+        // Find locations of the regions based on markers provided
+        let expectedLocations = 
+          [ for ms, me in regionMarkers do
+              MoveCursorToEndOfMarker(file, ms)
+              let sl, sc = GetCursorLocation(file)
+              MoveCursorToStartOfMarker(file, me)
+              let el, ec = GetCursorLocation(file)
+              // -1 to adjust line to VS format
+              // -1 to adjust columns (not quite sure why..)
+              yield (sl-1, sc-1), (el-1, ec-1) ]
+              
+        // Test whether the regions are same and that no 'update' commands are created (no regions exist prior to this call)
+        let toCreate, toUpdate = GetHiddenRegionCommands(file)
+        if (toUpdate <> Map.empty<_,_>) then 
+            Assert.Fail("Hidden regions, first call. Didn't expect any regions to update.")
+        AssertEqualWithMessage(expectedLocations.Length, toCreate.Length, "Different number of regions!")
+        AssertRegionListContains(expectedLocations, toCreate)
+
+        (* Files for testing and tests --------------------------------------------------------- *)
+                
+    static member NavigationFile1 = 
+      [ "#light"
+        "module Example.Module"
+        ""
+        "module SomeModule = "
+        "    type Rec = (*1s*){"
+        "      RFirst : int "
+        "      RSecond : string }(*1e*)"
+        ""
+        "    type Rec2 = "
+        "    (*2s*){ R2First : int "
+        "            R2Second : string "
+        "          }(*2e*)"
+        ""
+        "    type Abbrev = (*3s*)Microsoft.FSharp.Collections.List<int * string>(*3e*)"
+        ""
+        "    type Enum = "
+        "(*4s*)| Aaa = 0"
+        "      | Bbb = 3(*4e*)"
+        ""
+        "    type EnumOneLine = (*5s*)| OUAaa = 0 | OUBbb = 3(*5e*)" ]
+
+    [<Test>]
+    member public this.``Regions.NavigationFile1``() =        
+        this.TestHiddenRegions NavigationBarTests.NavigationFile1
+          [ "(*1s*)", "(*1e*)"
+            "(*2s*)", "(*2e*)" 
+            "(*3s*)", "(*3e*)"
+            "(*4s*)", "(*4e*)"
+            "(*5s*)", "(*5e*)"
+            "SomeModule", "(*5e*)" (* entire module *) ]
+                          
+    [<Test>]
+    [<Category("PerfCheck")>]
+    member public this.``Record1``() =        
+        this.TestNavigationBar NavigationBarTests.NavigationFile1 "SomeModule.Rec" ["RFirst"; "RSecond"]
+        
+    [<Test>]
+    member public this.``Record2``() =        
+        this.TestNavigationBar NavigationBarTests.NavigationFile1 "SomeModule.Rec2" ["R2First"; "R2Second"]
+          
+    [<Test>]
+    member public this.``Abbreviation``() =        
+        this.TestNavigationBar NavigationBarTests.NavigationFile1 "SomeModule.Abbrev" []
+
+    [<Test>]
+    member public this.``Enum``() =        
+        this.TestNavigationBar NavigationBarTests.NavigationFile1 "SomeModule.Enum" [ "Aaa"; "Bbb" ]
+
+    [<Test>]
+    member public this.``Enum.OneLine``() =        
+        this.TestNavigationBar NavigationBarTests.NavigationFile1 "SomeModule.EnumOneLine" [ "OUAaa"; "OUBbb" ]
+
+    static member NavigationFile2 = 
+      [ "#light"
+        "module A =   "
+        ""
+        "    type RecWith = (*7s*){ "
+        "        WRFirst : int "
+        "        WRSecond : string } with"
+        "      member zz.RecMember(s:string) = "
+        "        printfn \"recdmember\""
+        "        3(*7e*)"
+        ""
+        "module B =   "
+        "    type Union = "
+        "(*8s*)| UFirst"
+        "      | USecond of int * string"
+        "      member x.A = 0(*8e*)"
+        ""
+        "    type A() = "
+        "(*9s*)let rec a = (fun () -> b)"
+        "      and b = a() + 1"
+        "      member xx.Prop = 10"
+        "      member x.Func() = ()"
+        "      interface System.IDisposable with"
+        "        member x.Dispose() = ()(*9e*)"
+        ""
+        "    exception SomeCrash of (*10s*)int * string * list<unit>(*10e*)"
+        "    "
+        "    module MyList = (*11s*)Microsoft.FSharp.Collections.List(*11e*)"
+        ""
+        "    module MoreNested = "
+        "        type MyEnum ="
+        "     (*12s*)| One = 1"
+        "            | Two = 2"
+        "            | Three = 3(*12e*)"
+        "      "
+        "    type AExt with // this isn't valid extension, but it's ok for the parser"
+        "(*13s*)member x.Extension1() = 2"
+        "       member x.Extension2() = 2(*13e*) // TODO: this doesn't work correctly"
+        "          "
+        "    type Z() ="
+        "(*14s*)let mutable cache = 0"
+        "       member x.Z : int =  // type annotation can cause issues"
+        "         0(*14e*)"
+        ""
+        "    module (*15s*)FooBaz = // collapsed immediately after the identifier"
+        "      let toplevel () = "
+        "        let nested = 10"
+        "        0"
+        "      "
+        "      module (*16s*)NestedModule = "
+        "        let nestedThing () ="
+        "          0(*16e*)"
+        "          "
+        "      module OtherNested ="
+        "        let aa () ="
+        "          1(*15e*)        " ]
+    
+    [<Test>]
+    member public this.``Record.WithMembers``() =        
+        this.TestNavigationBar NavigationBarTests.NavigationFile2 "A.RecWith" ["WRFirst"; "WRSecond"; "RecMember" ]
+        
+    [<Test>]
+    member public this.``Union.WithMembers``() =        
+        this.TestNavigationBar NavigationBarTests.NavigationFile2 "B.Union" ["UFirst"; "USecond"; "A"]
+          
+    [<Test>]
+    member public this.``Class``() =        
+        this.TestNavigationBar NavigationBarTests.NavigationFile2 "B.A" ["Prop"; "Func"; "Dispose"] // perhaps IDisposable.Dispose
+
+    [<Test>]
+    member public this.``Exception``() =        
+        this.TestNavigationBar NavigationBarTests.NavigationFile2 "B.SomeCrash" [ ]
+        
+    [<Test>]
+    member public this.``Module.Alias``() =        
+        this.TestNavigationBar NavigationBarTests.NavigationFile2 "B.MyList" [ ]
+
+    [<Test>]
+    member public this.``NestedEnum``() =        
+        this.TestNavigationBar NavigationBarTests.NavigationFile2 "B.MoreNested.MyEnum" [ "One"; "Two"; "Three" ]
+
+    [<Test>]
+    member public this.``Extension``() =        
+        this.TestNavigationBar NavigationBarTests.NavigationFile2 "B.AExt" [ "Extension1"; "Extension2" ]
+        
+    [<Test>]
+    member public this.``Type.EndingWithProperty.WithTypeAnnotation``() =        
+        this.TestNavigationBar NavigationBarTests.NavigationFile2 "B.Z" [ "Z" ]   
+             
+    [<Test>]
+    member public this.``Module.Nested``() =        
+        this.TestNavigationBar NavigationBarTests.NavigationFile2 "B.FooBaz" [ "toplevel" ]
+
+    [<Test>]
+    member public this.``Module.Nested.More``() =        
+        this.TestNavigationBar NavigationBarTests.NavigationFile2 "B.FooBaz.NestedModule" [ "nestedThing" ]   
+
+// Allow the NavigationBarTests run under different context
+namespace UnitTests.Tests.LanguageService.NavigationBar
+open UnitTests.Tests.LanguageService
+open UnitTests.TestLib.LanguageService
+open UnitTests.TestLib.ProjectSystem
+open NUnit.Framework
+open Salsa.Salsa
+
+// context msbuild
+[<TestFixture>] 
+[<Category("LanguageService.MSBuild")>]
+type ``MSBuild`` = 
+   inherit NavigationBarTests
+   new() = { inherit NavigationBarTests(VsOpts = fst (Models.MSBuild())); }
+
+// Context project system
+[<TestFixture>] 
+[<Category("LanguageService.ProjectSystem")>]
+type ``ProjectSystem`` = 
+    inherit NavigationBarTests
+    new() = { inherit NavigationBarTests(VsOpts = LanguageServiceExtension.ProjectSystem); } 
\ No newline at end of file
diff --git a/vsintegration/src/unittests/Tests.LanguageService.ParameterInfo.fs b/vsintegration/src/unittests/Tests.LanguageService.ParameterInfo.fs
new file mode 100644
index 0000000..00c6173
--- /dev/null
+++ b/vsintegration/src/unittests/Tests.LanguageService.ParameterInfo.fs
@@ -0,0 +1,2265 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+namespace UnitTests.Tests.LanguageService
+
+open System
+open NUnit.Framework
+open Salsa.Salsa
+open Salsa.VsOpsUtils
+open UnitTests.TestLib.Salsa
+open UnitTests.TestLib.Utils
+open UnitTests.TestLib.LanguageService
+
+exception NoParamInfo
+[<AutoOpen>]
+module ParamInfoStandardSettings = 
+    let standard40AssemblyRefs  = [| "System"; "System.Core"; "System.Numerics" |]
+    let queryAssemblyRefs = [ "System.Xml.Linq"; "System.Core" ]
+
+type ParameterInfoTests()  = 
+    inherit LanguageServiceBaseTests()
+
+    let GetParamDisplays(methods:Microsoft.VisualStudio.FSharp.LanguageService.MethodListForAMethodTip) =
+            [ for i = 0 to methods.GetCount() - 1 do
+                yield [ for j = 0 to methods.GetParameterCount(i) - 1 do
+                            let (name,display,description) = methods.GetParameterInfo(i,j) 
+                            yield display ] ]
+      
+    let AssertEmptyMethodGroup(resultMethodGroup:Microsoft.VisualStudio.FSharp.LanguageService.MethodListForAMethodTip) =
+        Assert.AreEqual(null, resultMethodGroup, "Expected an empty method group")              
+        
+    let AssertMethodGroupDesciptionsDoNotContain(methods:Microsoft.VisualStudio.FSharp.LanguageService.MethodListForAMethodTip, expectNotToBeThere) = 
+        for i = 0 to methods.GetCount() - 1 do
+            let description = methods.GetDescription(i)
+            if (description.Contains(expectNotToBeThere)) then
+                Console.WriteLine("Expected description {0} to not contain {1}", description, expectNotToBeThere)
+                AssertNotContains(description,expectNotToBeThere)
+ 
+    let AssertMethodGroup(resultMethodGroup:Microsoft.VisualStudio.FSharp.LanguageService.MethodListForAMethodTip, expectedParamNamesSet:string list list) =
+        Assert.AreEqual(expectedParamNamesSet.Length, resultMethodGroup.GetCount())           
+        Assert.IsTrue(resultMethodGroup 
+                         |> GetParamDisplays
+                         |> Seq.forall (fun paramDisplays -> 
+                                expectedParamNamesSet |> List.exists (fun expectedParamNames -> 
+                                       expectedParamNames.Length = paramDisplays.Length && 
+                                       (expectedParamNames,paramDisplays) ||> List.forall2 (fun expectedParamName paramDisplay -> 
+                                           paramDisplay.Contains(expectedParamName)))))
+    
+    let AssertMethodGroupContain(resultMethodGroup:Microsoft.VisualStudio.FSharp.LanguageService.MethodListForAMethodTip, expectedParamNames:string list) = 
+        Assert.IsTrue(resultMethodGroup
+                          |> GetParamDisplays
+                          |> Seq.exists (fun paramDisplays ->
+                                expectedParamNames.Length = paramDisplays.Length &&
+                                (expectedParamNames,paramDisplays) ||> List.forall2 (fun expectedParamName paramDisplay -> 
+                                           paramDisplay.Contains(expectedParamName))))
+
+    member private this.GetMethodListForAMethodTip(fileContents : string, marker : string, ?addtlRefAssy : list<string>) = 
+        let (solution, project, file) = this.CreateSingleFileProject(fileContents, ?references = addtlRefAssy)
+
+        MoveCursorToStartOfMarker(file, marker)
+
+        GetParameterInfoAtCursor(file)
+
+     //Verify all the overload method parameterInfo 
+    member private this.VerifyParameterInfoAtStartOfMarker(fileContents : string, marker : string, expectedParamNamesSet:string list list, ?addtlRefAssy :list<string>) =
+        let methodstr = 
+            match addtlRefAssy with
+            |None -> this.GetMethodListForAMethodTip(fileContents,marker)
+            |Some(x) -> this.GetMethodListForAMethodTip(fileContents,marker,x)
+        AssertMethodGroup(methodstr,expectedParamNamesSet)
+
+   //Verify No parameterInfo at the marker     
+    member private this.VerifyNoParameterInfoAtStartOfMarker(fileContents : string, marker : string, ?addtlRefAssy : list<string>) =
+        let methodstr = 
+            match addtlRefAssy with
+            |None -> this.GetMethodListForAMethodTip(fileContents,marker)
+            |Some(x) -> this.GetMethodListForAMethodTip(fileContents,marker,x)
+        AssertEmptyMethodGroup(methodstr)
+
+    //Verify one method parameterInfo if contained in parameterInfo list
+    member private this.VerifyParameterInfoContainedAtStartOfMarker(fileContents : string, marker : string, expectedParamNames:string list, ?addtlRefAssy : list<string>) =
+        let methodstr = 
+            match addtlRefAssy with
+            |None -> this.GetMethodListForAMethodTip(fileContents,marker)
+            |Some(x) -> this.GetMethodListForAMethodTip(fileContents,marker,x)
+        AssertMethodGroupContain(methodstr,expectedParamNames)
+
+    //Verify the parameterInfo of one of the list order
+    member private this.VerifyParameterInfoOverloadMethodIndex(fileContents : string, marker : string, index : int, expectedParams:string list, ?addtlRefAssy : list<string>) = 
+        let methodstr = 
+            match addtlRefAssy with
+            |None -> this.GetMethodListForAMethodTip(fileContents,marker)
+            |Some(x) -> this.GetMethodListForAMethodTip(fileContents,marker,x)
+
+        let GetPramDisplaysByIndex(methods:Microsoft.VisualStudio.FSharp.LanguageService.MethodListForAMethodTip) =
+            [ for i = 0 to methods.GetParameterCount(index) - 1 do
+                let (name,display,description) = methods.GetParameterInfo(index,i)
+                yield display]
+        let paramDisplays = GetPramDisplaysByIndex methodstr
+        Assert.IsTrue((expectedParams, paramDisplays) ||> List.forall2 (fun expectedParam paramDisplay -> 
+                                        paramDisplay.Contains(expectedParam)))
+    //Verify there is at least one parameterInfo
+    member private this.VerifyHasParameterInfo(fileContents : string, marker : string) =
+        let methodstr = this.GetMethodListForAMethodTip(fileContents,marker)
+        Assert.IsTrue (methodstr.GetCount() > 0)
+    //Verify return content after the colon
+    member private this.VerifyFirstParameterInfoColonContent(fileContents : string, marker : string, expectedStr : string, ?addtlRefAssy : list<string>) =
+        let methodstr = 
+            match addtlRefAssy with
+            |None -> this.GetMethodListForAMethodTip(fileContents,marker)
+            |Some(x) -> this.GetMethodListForAMethodTip(fileContents,marker,x)
+
+        Assert.AreEqual(expectedStr, methodstr.GetType(0)) // Expecting a method info like X(a:int,b:int) : int [used to be  X(a:int,b:int) -> int]
+
+    [<Test>]
+    member public this.``Regression.OnConstructor.881644``() =
+        let fileContent = """new System.IO.StreamReader((*Mark*)"""
+        let methodstr = this.GetMethodListForAMethodTip(fileContent,"(*Mark*)")
+        if not (methodstr.GetDescription(0).Contains("#ctor")) then
+            failwith "Expected parameter info to contain #ctor"
+
+    [<Test>]
+    member public this.``Regression.InsideWorkflow.6437``() =
+        let fileContent = """
+            open System.IO 
+            let computation2 =
+                async { use file = File.Open("",FileMode.Open)
+                        let! buffer = file.AsyncRead((*Mark*)0)
+                        return 0 }"""
+        let methodstr = this.GetMethodListForAMethodTip(fileContent,"(*Mark*)")
+        if not (methodstr.GetDescription(0).Contains("AsyncRead")) then
+            failwith "Expected parameter info to contain AsyncRead"
+    
+    [<Test>]
+    [<Category("PerfCheck")>]
+    member public this.``Regression.MethodInfo.WithColon.Bug4518_1``() =
+        let fileContent = """
+            type T() =
+                member this.X
+                    with set ((a:int), (b:int)) (c:int) = ()
+            ((new T()).X((*Mark*)"""
+        this.VerifyFirstParameterInfoColonContent(fileContent,"(*Mark*)",": int")
+    
+    [<Test>]
+    member public this.``Regression.MethodInfo.WithColon.Bug4518_2``() =
+        let fileContent = """
+           type IFoo = interface
+                abstract f : int -> int
+                    end
+           let i : IFoo = null
+           i.f((*Mark*)"""
+        this.VerifyFirstParameterInfoColonContent(fileContent,"(*Mark*)",": int")
+        
+    [<Test>]
+    member public this.``Regression.MethodInfo.WithColon.Bug4518_3``() =
+        let fileContent = """
+           type M() = 
+                member this.f x = ()
+           let m = new M()
+           m.f((*Mark*)"""
+        this.VerifyFirstParameterInfoColonContent(fileContent,"(*Mark*)",": unit")
+        
+    [<Test>]
+    member public this.``Regression.MethodInfo.WithColon.Bug4518_4``() =
+        let fileContent = """
+           type T() =
+                member this.Foo(a,b) = ""
+           let t = new T()
+           t.Foo((*Mark*)"""
+        this.VerifyFirstParameterInfoColonContent(fileContent,"(*Mark*)",": string")    
+        
+    [<Test>]
+    member public this.``Regression.MethodInfo.WithColon.Bug4518_5``() =
+        let fileContent = """
+           let f x y = x + y
+           f((*Mark*)"""
+        this.VerifyFirstParameterInfoColonContent(fileContent,"(*Mark*)",": int -> int ")  
+
+    [<Test>]
+    member public this.``Regression.StaticVsInstance.Bug3626.Case1``() =
+        let fileContent = """
+            type Foo() = 
+                member this.Bar(instanceReturnsString:int) = "hllo"
+                static member Bar(staticReturnsInt:int) = 13
+            let z = Foo.Bar((*Mark*))"""
+        this.VerifyParameterInfoAtStartOfMarker(fileContent,"(*Mark*)",[["staticReturnsInt"]])
+
+    [<Test>]
+    member public this.``Regression.StaticVsInstance.Bug3626.Case2``() =
+        let fileContent = """
+            type Foo() = 
+                member this.Bar(instanceReturnsString:int) = "hllo"
+                static member Bar(staticReturnsInt:int) = 13
+            let Hoo = new Foo()
+            let y = Hoo.Bar((*Mark*)"""
+        this.VerifyParameterInfoAtStartOfMarker(fileContent,"(*Mark*)",[["instanceReturnsString"]])
+
+    [<Test>]
+    member public this.``Regression.MethodInfo.Bug808310``() =
+        let fileContent = """System.Console.WriteLine((*Mark*)"""
+        let methodGroup = this.GetMethodListForAMethodTip(fileContent,"(*Mark*)")   
+        let description = methodGroup.GetDescription(0)
+        // Make sure that System.Console.WriteLine is not mentioned anywhere exception in the XML comment signature
+        let xmlCommentIndex = description.IndexOf("System.Console.WriteLine]")
+        let noBracket =       description.IndexOf("System.Console.WriteLine")
+        Assert.IsTrue(noBracket>=0)
+        Assert.AreEqual(noBracket, xmlCommentIndex)
+
+    [<Test>]
+    member public this.``NoArguments``() =
+        // we want to see e.g. 
+        //     g() : int
+        // and not
+        //     g(unit) : int
+        let fileContents = """
+            type T =
+                static member F() = 42
+                static member G(x:unit) = 42
+
+            let r1 = T.F((*1*))
+            let r2 = T.G((*2*))
+
+            let g() = 42
+            let h((x:unit)) = 42
+            let r3 = h((*3*))
+            let r4 = g((*4*))"""
+        Assert.AreEqual(0, this.GetMethodListForAMethodTip(fileContents,"(*1*)").GetParameterCount(0))
+        Assert.AreEqual(0, this.GetMethodListForAMethodTip(fileContents,"(*2*)").GetParameterCount(0))
+        Assert.AreEqual(0, this.GetMethodListForAMethodTip(fileContents,"(*3*)").GetParameterCount(0))
+        Assert.AreEqual(0, this.GetMethodListForAMethodTip(fileContents,"(*4*)").GetParameterCount(0))
+
+    [<Test>]
+    member public this.``Single.Constructor1``() =
+        let fileContent = """new System.DateTime((*Mark*)"""
+        this.VerifyHasParameterInfo(fileContent, "(*Mark*)")
+    
+    [<Test>]
+    member public this.``Single.Constructor2``() =
+        let fileContent = """
+            open System
+            new DateTime((*Mark*)"""
+        this.VerifyHasParameterInfo(fileContent, "(*Mark*)")
+
+    [<Test>]
+    member public this.``Single.DotNet.StaticMethod``() =
+        let code = 
+                                    ["#light"
+                                     "System.Object.ReferenceEquals("
+                                    ]
+        let (_, _, file) = this.CreateSingleFileProject(code)
+        let gpatcc = GlobalParseAndTypeCheckCounter.StartNew(this.VS)
+        MoveCursorToEndOfMarker(file,"Object.ReferenceEquals(")
+        let methodGroup = GetParameterInfoAtCursor file
+        AssertMethodGroup(methodGroup, [["objA"; "objB"]])
+        gpatcc.AssertExactly(0,0)
+
+    [<Test>]
+    member public this.``Regression.NoParameterInfo.100I.Bug5038``() =
+        let fileContent = """100I((*Mark*)"""
+        this.VerifyNoParameterInfoAtStartOfMarker(fileContent,"(*Mark*)")
+
+    [<Test>]
+    member public this.``Single.DotNet.InstanceMethod``() =
+        let fileContent = """
+            let s = "Hello"
+            s.Substring((*Mark*)"""
+        this.VerifyParameterInfoAtStartOfMarker(fileContent,"(*Mark*)",[["startIndex"]; ["startIndex"; "length"]])
+    
+    [<Test>]
+    member public this.``Single.BasicFSharpFunction``() =
+        let fileContent = """
+            let foo(x) = 1
+            foo((*Mark*)"""
+        this.VerifyParameterInfoAtStartOfMarker(fileContent,"(*Mark*)",[["'a"]])
+        
+    [<Test>]
+    member public this.``Single.DiscriminatedUnion.Construction``() =
+        let fileContent = """
+            type MyDU = 
+              | Case1 of int * string
+              | Case2 of V1 : int * string * V3 : bool
+              | Case3 of ``Long Name`` : int * Item2 : string
+              | Case4 of int
+              
+            let x1 = Case1((*Mark1*)
+            let x2 = Case2((*Mark2*)
+            let x3 = Case3((*Mark3*)
+            let x4 = Case4((*Mark4*)
+            """
+
+        this.VerifyParameterInfoAtStartOfMarker(fileContent,"(*Mark1*)",[["int"; "string"]])
+        this.VerifyParameterInfoAtStartOfMarker(fileContent,"(*Mark2*)",[["V1: int"; "string"; "V3: bool"]])
+        this.VerifyParameterInfoAtStartOfMarker(fileContent,"(*Mark3*)",[["Long Name: int"; "string"]])
+        this.VerifyParameterInfoAtStartOfMarker(fileContent,"(*Mark4*)",[["int"]])
+        
+    [<Test>]
+    member public this.``Single.Exception.Construction``() =
+        let fileContent = """
+            exception E1 of int * string
+            exception E2 of V1 : int * string * V3 : bool
+            exception E3 of ``Long Name`` : int * Data1 : string
+              
+            let x1 = E1((*Mark1*)
+            let x2 = E2((*Mark2*)
+            let x3 = E3((*Mark3*)
+            """
+
+        this.VerifyParameterInfoAtStartOfMarker(fileContent,"(*Mark1*)",[["int"; "string"]])
+        this.VerifyParameterInfoAtStartOfMarker(fileContent,"(*Mark2*)",[["V1: int"; "string"; "V3: bool" ]])
+        this.VerifyParameterInfoAtStartOfMarker(fileContent,"(*Mark3*)",[["Long Name: int"; "string" ]])
+    
+    [<Test>]
+    [<Category("TypeProvider")>]
+    [<Category("TypeProvider.StaticParameters")>]
+    //This test verifies that ParamInfo on a provided type that exposes one (static) method that takes one argument works normally.
+    member public this.``TypeProvider.StaticMethodWithOneParam`` () =
+        let fileContent = """
+            let foo = N1.T1.M1((*Marker*)
+            """
+        this.VerifyParameterInfoAtStartOfMarker(fileContent,"(*Marker*)",[["arg1"]],
+            addtlRefAssy = [System.IO.Path.Combine(System.Environment.CurrentDirectory,@"UnitTestsResources\MockTypeProviders\DummyProviderForLanguageServiceTesting.dll")])
+                  
+    [<Test>]
+    [<Category("TypeProvider")>]
+    [<Category("TypeProvider.StaticParameters")>]
+    //This test verifies that ParamInfo on a provided type that exposes a (static) method that takes >1 arguments works normally.
+    member public this.``TypeProvider.StaticMethodWithMoreParam`` () =
+        let fileContent = """
+            let foo = N1.T1.M2((*Marker*)
+            """
+        this.VerifyParameterInfoAtStartOfMarker(fileContent,"(*Marker*)",[["arg1";"arg2"]],
+            addtlRefAssy = [System.IO.Path.Combine(System.Environment.CurrentDirectory,@"UnitTestsResources\MockTypeProviders\DummyProviderForLanguageServiceTesting.dll")])
+    
+    [<Test>]
+    [<Category("TypeProvider")>]
+    [<Category("TypeProvider.StaticParameters")>]
+    //This test case verify the TypeProvider static method return type or colon content of the method
+    //This test verifies that ParamInfo on a provided type that exposes one (static) method that takes one argument
+    //and returns something works correctly (more precisely, it checks that the return type is 'int')
+    member public this.``TypeProvider.StaticMethodColonContent`` () =
+        let fileContent = """
+            let foo = N1.T1.M2((*Marker*)
+            """
+        this.VerifyFirstParameterInfoColonContent(fileContent,"(*Marker*)",": int",
+            addtlRefAssy = [System.IO.Path.Combine(System.Environment.CurrentDirectory,@"UnitTestsResources\MockTypeProviders\DummyProviderForLanguageServiceTesting.dll")])
+    
+
+    [<Test>]
+    [<Category("TypeProvider")>]
+    [<Category("TypeProvider.StaticParameters")>]
+    //This test verifies that ParamInfo on a provided type that exposes a Constructor that takes no argument works normally.
+    member public this.``TypeProvider.ConstructorWithNoParam`` () =
+        let fileContent = """
+            let foo = new N1.T1((*Marker*)
+            """
+        this.VerifyParameterInfoOverloadMethodIndex(fileContent,"(*Marker*)",0,[],
+            addtlRefAssy = [System.IO.Path.Combine(System.Environment.CurrentDirectory,@"UnitTestsResources\MockTypeProviders\DummyProviderForLanguageServiceTesting.dll")])
+              
+    [<Test>]
+    [<Category("TypeProvider")>]
+    [<Category("TypeProvider.StaticParameters")>]
+    //This test verifies that ParamInfo on a provided type that exposes a Constructor that takes one argument works normally.
+    member public this.``TypeProvider.ConstructorWithOneParam`` () =
+        let fileContent = """
+            let foo = new N1.T1((*Marker*)
+            """
+        this.VerifyParameterInfoOverloadMethodIndex(fileContent,"(*Marker*)",1,["arg1"],
+            addtlRefAssy = [System.IO.Path.Combine(System.Environment.CurrentDirectory,@"UnitTestsResources\MockTypeProviders\DummyProviderForLanguageServiceTesting.dll")])
+         
+    [<Test>]
+    [<Category("TypeProvider")>]
+    [<Category("TypeProvider.StaticParameters")>]
+    //This test verifies that ParamInfo on a provided type that exposes a Constructor that takes >1 argument works normally.
+    member public this.``TypeProvider.ConstructorWithMoreParam`` () =
+        let fileContent = """
+            let foo = new N1.T1((*Marker*)
+            """
+        this.VerifyParameterInfoOverloadMethodIndex(fileContent,"(*Marker*)",2,["arg1";"arg2"],
+            addtlRefAssy = [System.IO.Path.Combine(System.Environment.CurrentDirectory,@"UnitTestsResources\MockTypeProviders\DummyProviderForLanguageServiceTesting.dll")])
+         
+    [<Test>]
+    [<Category("TypeProvider")>]
+    [<Category("TypeProvider.StaticParameters")>]
+    //This test verifies that ParamInfo on a provided type that exposes a static parameter that takes >1 argument works normally.
+    member public this.``TypeProvider.Type.WhenOpeningBracket`` () =
+        let fileContent = """
+            type foo = N1.T<(*Marker*)
+            """
+        this.VerifyParameterInfoAtStartOfMarker(fileContent,"(*Marker*)",[["Param1";"ParamIgnored"]],
+            addtlRefAssy = [System.IO.Path.Combine(System.Environment.CurrentDirectory,@"UnitTestsResources\MockTypeProviders\DummyProviderForLanguageServiceTesting.dll")])
+        
+    [<Test>]
+    [<Category("TypeProvider")>]
+    [<Category("TypeProvider.StaticParameters")>]
+    //This test verifies that after closing bracket ">" the ParamInfo isn't showing on a provided type that exposes a static parameter that takes >1 argument works normally.
+    //This is a regression test for Bug DevDiv:181000
+    member public this.``TypeProvider.Type.AfterCloseBracket`` () =
+        let fileContent = """
+            type foo = N1.T< "Hello", 2>(*Marker*)
+            """
+        this.VerifyNoParameterInfoAtStartOfMarker(fileContent,"(*Marker*)",
+            addtlRefAssy = [System.IO.Path.Combine(System.Environment.CurrentDirectory,@"UnitTestsResources\MockTypeProviders\DummyProviderForLanguageServiceTesting.dll")])
+    
+    [<Test>]
+    [<Category("TypeProvider")>]
+    [<Category("TypeProvider.StaticParameters")>]
+    //This test verifies that ParamInfo is showing after delimiter "," on a provided type that exposes a static parameter that takes >1 argument works normally.
+    member public this.``TypeProvider.Type.AfterDelimiter`` () =
+        let fileContent = """
+            type foo = N1.T<"Hello",(*Marker*)
+            """
+        this.VerifyParameterInfoContainedAtStartOfMarker(fileContent,"(*Marker*)",["Param1";"ParamIgnored"],
+             [System.IO.Path.Combine(System.Environment.CurrentDirectory,@"UnitTestsResources\MockTypeProviders\DummyProviderForLanguageServiceTesting.dll")])
+        
+              
+    [<Test>]
+    member public this.``Single.InMatchClause``() =
+        let fileContent = """
+            let rec f l = 
+                match l with
+                | [] -> System.String.Format((*Mark*)
+                | x :: xs -> f xs"""
+        this.VerifyParameterInfoAtStartOfMarker(fileContent,"(*Mark*)",[["format"; "arg0"];
+                                                                        ["format"; "args"];
+                                                                        ["provider"; "format"; "args"];
+                                                                        ["format"; "arg0"; "arg1"];
+                                                                        ["format"; "arg0"; "arg1"; "arg2"]])
+  
+    (* --- Parameter Info Systematic Tests ------------------------------------------------- *)
+
+    member public this.TestSystematicParameterInfo (marker, methReq, ?startOfMarker) =
+        let code = 
+                                   ["let arr = "
+                                    "    seq { for c = 'a' to 'z' do yield c }"
+                                    "    |> Seq.map ( fun c ->"
+                                    "        async { let x = c.ToString() in"
+                                    "                return System.String.Format(\"[{0}] for [{1}]\"(*loc-1*), x.ToUpperInvariant()(*loc-2*), c) })"
+                                    "    |> Async.Parallel"
+                                    "    |> Async.RunSynchronously"
+
+                                    "let (alist: System.Collections.ArrayList) = System.Collections.ArrayList(2)"
+                                    "alist.[0] |> ignore"
+                                    "<@@ let x = 1 in x(*loc-8*) @@>"
+
+                                    "type FunkyType ="
+                                    "    private (*loc-4*)new() = {}"
+                                    "    static member ConvertToInt32 (s : string) ="
+                                    "        let mutable n = 0 in"
+                                    "        let parseRes = System.Int32.TryParse(s, &n) in"
+                                    "        if not parseRes then"
+                                    "            raise (new System.ArgumentException(\"incorrect number format\"))"
+                                    "        n"
+
+                                    "type Fruit = | Apple | Banana"
+                                    "type KeyValuePair = { Key : int; Value : float }"
+                                    "let print (x : Fruit, kvp : KeyValuePair) = System.Console.WriteLine(x); System.Console.WriteLine(kvp)"
+                                    "print ((*loc-9*)Banana, {Key = 0; Value = 0.0})"
+
+                                    "type Emp = "
+                                    "    [<DefaultValue((*loc-6*)true)>]"
+                                    "    static val mutable private m_ID : int"
+                                    "    static member private NextID () = Emp.m_ID <- Emp.m_ID + 1; Emp.m_ID"
+                                    "    val mutable private m_EmpID   : int"
+                                    "    val mutable private m_Name    : string"
+                                    "    val mutable private m_Salary  : float"
+                                    "    val mutable private m_DoB     : System.DateTime"
+                                    "    (*loc-5*)"
+
+                                    "    // Overloaded Constructors"
+                                    "    public new() ="
+                                    "       { m_EmpID  = Emp.NextID();"
+                                    "         m_Name   = System.String.Empty;"
+                                    "         m_Salary = 0.0;"
+                                    "         m_DoB    = System.DateTime.Today }"
+
+                                    "    public new(name, salary, dob) as self = "
+                                    "       new Emp() then"
+                                    "         self.m_Name   <- name"
+                                    "         self.m_Salary <- salary"
+                                    "         self.m_DoB    <- dob"
+
+                                    "    public new(name, dob) ="
+                                    "        new (*loc-3*)Emp(name, 0.0, dob)"
+
+                                    "    // Overloaded methods"
+                                    "    member this.IncreaseBy(amount : float  ) = this.m_Salary <- this.m_Salary + amount"
+                                    "    member this.IncreaseBy(amount : int    ) = this.IncreaseBy(float(amount))"
+                                    "    member this.IncreaseBy(amount : float32) = this.IncreaseBy(float(amount))"
+
+                                    "let ``Random Number Generator`` = System.Random()"
+                                    "let ``?Max!Value?`` = 100"
+                                    "let swap (a, b) = (b, a)"
+
+                                    "[ \"Kevin\", System.DateTime.Today.AddYears(-25); \"John\", new System.DateTime(1980, 1, 1) ]"
+                                    "|> List.map ( fun a -> let pair = swap a in Emp(dob = fst pair, name = snd pair) )"
+                                    "|> List.iter ( fun a -> a.IncreaseBy(``Random Number Generator``.Next((*loc-7*)``?Max!Value?``)) )"
+                                    
+                                    "System.Console.ReadLine("
+                                    ]
+        let (_, _, file) = this.CreateSingleFileProject(code)
+        match startOfMarker with
+        | Some(start) when start = true
+            -> MoveCursorToStartOfMarker(file, marker)
+        | _ -> MoveCursorToEndOfMarker(file, marker)
+        
+        let methodGroup = GetParameterInfoAtCursor file
+        if (methReq = []) then
+            AssertEqual(null, methodGroup)
+        else
+            AssertMethodGroup(methodGroup, methReq)
+            
+    // Test on .NET functions with no parameter
+    [<Test>]
+    member public this.``Single.DotNet.NoParameters`` () = 
+        this.TestSystematicParameterInfo("x.ToUpperInvariant(", [ [] ])
+
+    // Test on .NET function with one parameter
+    [<Test>]
+    member public this.``Single.DotNet.OneParameter`` () = 
+        this.TestSystematicParameterInfo("System.DateTime.Today.AddYears(", [ ["value: int"] ] )
+
+    // Test appearance of PI on second parameter of .NET function
+    [<Test>]
+    [<Ignore("FSharp1.0:2394")>]
+    member public this.``Single.DotNet.OnSecondParameter`` () = 
+        this.TestSystematicParameterInfo("loc-1*),", [ ["format"; "args"];
+                                                       ["format"; "arg0"];
+                                                       ["provider"; "format"; "args"];
+                                                       ["format"; "arg0"; "arg1"];
+                                                       ["format"; "arg0"; "arg1"; "arg2"] ] )
+    // Test on .NET functions with parameter array
+    [<Test>]
+    [<Ignore("FSharp1.0:2394")>]
+    member public this.``Single.DotNet.ParameterArray`` () = 
+        this.TestSystematicParameterInfo("loc-2*),", [ ["format"; "args"];
+                                                       ["format"; "arg0"];
+                                                       ["provider"; "format"; "args"];
+                                                       ["format"; "arg0"; "arg1"];
+                                                       ["format"; "arg0"; "arg1"; "arg2"] ] )
+    // Test on .NET indexers
+    [<Test>]
+    [<Ignore("FSharp1.0:5245")>]
+    member public this.``Single.DotNet.IndexerParameter`` () = 
+        this.TestSystematicParameterInfo("alist.[", [ ["index: int"] ] )
+    
+    // Test on .NET parameters passed with 'out' keyword (byref)
+    [<Test>]
+    [<Ignore("FSharp1.0:2394")>]
+    member public this.``Single.DotNet.ParameterByReference`` () = 
+        this.TestSystematicParameterInfo("Int32.TryParse(s,", [ ["s: string"; "result: int byref"]; ["s"; "style"; "provider"; "result"] ] )
+        
+    // Test on reference type and value type paramaters (e.g. string & DateTime)
+    [<Test>]
+    member public this.``Single.DotNet.RefTypeValueType`` () = 
+        this.TestSystematicParameterInfo("loc-3*)Emp(", [ [];
+                                                          ["name: string"; "dob: System.DateTime"];
+                                                          ["name: string"; "salary: float"; "dob: System.DateTime"] ] )
+                                                          
+    // Test PI does not pop up at point of definition/declaration
+    [<Test>]
+    [<Ignore("FSharp1.0:5160")>]
+    member public this.``Single.Locations.PointOfDefinition`` () = 
+        this.TestSystematicParameterInfo("loc-4*)new(", [ ] )
+        this.TestSystematicParameterInfo("member ConvertToInt32 (", [ ] )
+        this.TestSystematicParameterInfo("member this.IncreaseBy(", [ ] )
+        
+    // Test PI does not pop up on whitespace after type annotation
+    [<Test>]
+    [<Ignore("FSharp1.0:5244")>]
+    member public this.``Single.Locations.AfterTypeAnnotation`` () = 
+        this.TestSystematicParameterInfo("(*loc-5*)", [], true)        
+
+
+    // Test PI does not pop up after non-parameterized properties
+    [<Test>]
+    member public this.``Single.Locations.AfterProperties`` () = 
+        this.TestSystematicParameterInfo("System.DateTime.Today", [])
+        //this.TestSystematicParameterInfo("(*loc-8*)", [], true)
+
+    // Test PI does not pop up after non-function values
+    [<Test>]
+    member public this.``Single.Locations.AfterValues`` () = 
+        this.TestSystematicParameterInfo("(*loc-8*)", [], true)
+    
+    // Test PI does not pop up after non-parameterized properties and after values
+    [<Test>]
+    member public this.``Single.Locations.EndOfFile`` () = 
+        this.TestSystematicParameterInfo("System.Console.ReadLine(", [ [] ])
+        
+    // Test PI pop up on parameter list for attributes
+    [<Test>]
+    [<Ignore("FSharp1.0:5242")>]
+    member public this.``Single.OnAttributes`` () = 
+        this.TestSystematicParameterInfo("(*loc-6*)", [ []; [ "check: bool" ] ], true)
+    
+    // Test PI when quoted identifiers are used as parameter
+    [<Test>]
+    member public this.``Single.QuotedIdentifier`` () = 
+        this.TestSystematicParameterInfo("(*loc-7*)", [ []; [ "maxValue" ]; [ "minValue"; "maxValue" ] ], true)
+        
+    // Test PI with parameters of custom type 
+    [<Test>]
+    member public this.``Single.RecordAndUnionType`` () = 
+        this.TestSystematicParameterInfo("(*loc-9*)", [ [ "Fruit"; "KeyValuePair" ] ], true)
+
+    (* --- End Of Parameter Info Systematic Tests ------------------------------------------ *)
+
+(* Tests for Generic parameterinfos -------------------------------------------------------- *)
+  
+    member private this.TestGenericParameterInfo (testLine, methReq) =
+        let code = [ "#light"; "open System"; "open System.Threading"; ""; testLine ]
+        let (_, _, file) = this.CreateSingleFileProject(code)
+        MoveCursorToEndOfMarker(file, testLine)
+        let methodGroup = GetParameterInfoAtCursor file
+        if (methReq = []) then
+            AssertEqual(null, methodGroup)
+        else
+            AssertMethodGroup(methodGroup, methReq)
+    
+    [<Test>]
+    member public this.``Single.Generics.Typeof``() =
+        let sevenTimes l = [ l; l; l; l; l; l; l ]
+        this.TestGenericParameterInfo("typeof<int>(", [])
+    [<Test>]
+    member public this.``Single.Generics.MathAbs``() =
+        let sevenTimes l = [ l; l; l; l; l; l; l ]
+        this.TestGenericParameterInfo("Math.Abs(", sevenTimes ["value"])
+    [<Test>]
+    member public this.``Single.Generics.ExchangeInt``() =
+        let sevenTimes l = [ l; l; l; l; l; l; l ]
+        this.TestGenericParameterInfo("Interlocked.Exchange<int>(", sevenTimes ["location1"; "value"])
+    [<Test>]
+    member public this.``Single.Generics.Exchange``() =
+        let sevenTimes l = [ l; l; l; l; l; l; l ]
+        this.TestGenericParameterInfo("Interlocked.Exchange(", sevenTimes ["location1"; "value"])
+    [<Test>]
+    member public this.``Single.Generics.ExchangeUnder``() =
+        let sevenTimes l = [ l; l; l; l; l; l; l ]
+        this.TestGenericParameterInfo("Interlocked.Exchange<_> (", sevenTimes ["location1"; "value"])
+    [<Test>]
+    member public this.``Single.Generics.Dictionary``() =
+        this.TestGenericParameterInfo("System.Collections.Generic.Dictionary<_, option<int>>(", [ []; ["capacity"]; ["comparer"]; ["capacity"; "comparer"]; ["dictionary"]; ["dictionary"; "comparer"] ])
+    [<Test>]
+    member public this.``Single.Generics.List``() =
+        this.TestGenericParameterInfo("new System.Collections.Generic.List< _ > ( ", [ []; ["capacity"]; ["collection"] ])
+    [<Test>]
+    member public this.``Single.Generics.ListInt``() =
+        this.TestGenericParameterInfo("System.Collections.Generic.List<int>(", [ []; ["capacity"]; ["collection"] ])
+    [<Test>]
+    member public this.``Single.Generics.EventHandler``() =
+        this.TestGenericParameterInfo("new System.EventHandler( ", [ [""] ]) // function arg doesn't have a name
+    [<Test>]
+    member public this.``Single.Generics.EventHandlerEventArgs``() =
+        this.TestGenericParameterInfo("System.EventHandler<EventArgs>(", [ [""] ]) // function arg doesn't have a name
+    [<Test>]
+    member public this.``Single.Generics.EventHandlerEventArgsNew``() =
+        this.TestGenericParameterInfo("new System.EventHandler<EventArgs> ( ", [ [""] ]) // function arg doesn't have a name
+
+    // Split into multiple lines using "\n" and find the index of "$" (and remove it from the text)
+    member private this.ExtractLineInfo (line:string) =
+        let idx, lines, foundDollar = line.Split([| '\r'; '\n' |], StringSplitOptions.RemoveEmptyEntries) |> List.ofArray |> List.foldBack (fun l (idx, lines, foundDollar) ->
+            let i = l.IndexOf("$")
+            if i = -1 then (idx, l::lines, foundDollar) 
+            else (l.Substring(0, i), l.Replace("$", "")::lines, true) ) <| ("", [], false)
+        if not foundDollar then
+            failwith "bad unit test: did not find '$' in input to mark cursor location!"
+        idx, lines
+        
+    member public this.TestParameterInfoNegative (testLine, ?addtlRefAssy : list<string>) =
+        let cursorPrefix, testLines = this.ExtractLineInfo testLine
+
+        let code = 
+                      [ "#light"
+                        "open System"
+                        "open System.Threading"
+                        "open System.Collections.Generic"; ""] @ testLines
+        let (_, _, file) = this.CreateSingleFileProject(code, ?references = addtlRefAssy)
+        let gpatcc = GlobalParseAndTypeCheckCounter.StartNew(this.VS)
+        MoveCursorToEndOfMarker(file, cursorPrefix)
+        let info = GetParameterInfoAtCursor file
+        AssertEqual(null, info)
+        gpatcc.AssertExactly(0,0)
+        
+    member public this.TestParameterInfoLocation (testLine, expectedPos, ?addtlRefAssy : list<string>) =
+        let cursorPrefix, testLines = this.ExtractLineInfo testLine
+        let code =
+                      [ "#light"
+                        "open System"
+                        "open System.Threading"
+                        "open System.Collections.Generic"; ""] @ testLines
+        let (_, _, file) = this.CreateSingleFileProject(code, ?references = addtlRefAssy)
+        MoveCursorToEndOfMarker(file, cursorPrefix)
+        let info = GetParameterInfoAtCursor file
+        AssertEqual(expectedPos, info.GetColumnOfStartOfLongId())
+
+    // Tests the current behavior, we may want to specify it differently in the future
+    // There are more comments below that explain particular tricky cases
+    
+
+    [<Test>]
+    member public this.``Single.Locations.Simple``() =
+        this.TestParameterInfoLocation("let a = System.Math.Sin($", 8)
+        
+    [<Test>]
+    member public this.``Single.Locations.LineWithSpaces``() =
+        this.TestParameterInfoLocation("let r =\n"+
+                                       "   System.Math.Abs($0)", 3) // on the beginning of "System", not line!
+        
+    [<Test>]
+    member public this.``Single.Locations.FullCall``() =
+        this.TestParameterInfoLocation("System.Math.Abs($0)", 0)
+        
+    [<Test>]
+    member public this.``Single.Locations.SpacesAfterParen``() =
+        this.TestParameterInfoLocation("let a = Math.Sign( $-10  )", 8)
+        
+    [<Test>]
+    member public this.``Single.Locations.WithNamespace``() =
+        this.TestParameterInfoLocation("let a = System.Threading.Interlocked.Exchange($", 8)
+        
+    [<Test>]
+    member public this.``ParameterInfo.Locations.WithoutNamespace``() =
+        this.TestParameterInfoLocation("let a = Interlocked.Exchange($", 8)
+        
+    [<Test>]
+    member public this.``Single.Locations.WithGenericArgs``() =
+        this.TestParameterInfoLocation("Interlocked.Exchange<int>($", 0)
+        
+    [<Test>]
+    member public this.``Single.Locations.FunctionWithSpace``() =
+        this.TestParameterInfoLocation("let a = sin 0$.0", 8) 
+        
+    [<Test>]
+    member public this.``Single.Locations.MethodCallWithoutParens``() =
+        this.TestParameterInfoLocation("let n = Math.Sin 1$0.0", 8)
+        
+    [<Test>]
+    member public this.``Single.Locations.GenericCtorWithNamespace``() =
+        this.TestParameterInfoLocation("let _ = new System.Collections.Generic.Dictionary<_, _>($)", 12) // on the beginning of "System" (not on "new")
+        
+    [<Test>]
+    member public this.``Single.Locations.GenericCtor``() =
+        this.TestParameterInfoLocation("let _ = new Dictionary<_, _>($)", 12) // on the beginning of "System" (not on "new")
+ 
+    [<Test>]
+    [<Category("TypeProvider")>]
+    [<Category("TypeProvider.StaticParameters")>]
+    //This test verifies that ParamInfo location on a provided type with namespace that exposes static parameter that takes >1 argument works normally.
+    member public this.``TypeProvider.Type.ParameterInfoLocation.WithNamespace`` () =
+        this.TestParameterInfoLocation("type boo = N1.T<$",11,
+            addtlRefAssy = [System.IO.Path.Combine(System.Environment.CurrentDirectory,@"UnitTestsResources\MockTypeProviders\DummyProviderForLanguageServiceTesting.dll")])
+ 
+    [<Test>]
+    [<Category("TypeProvider")>]
+    [<Category("TypeProvider.StaticParameters")>]
+    //This test verifies that ParamInfo location on a provided type without the namespace that exposes static parameter that takes >1 argument works normally.
+    member public this.``TypeProvider.Type.ParameterInfoLocation.WithOutNamespace`` () =
+        this.TestParameterInfoLocation("open N1 \n"+ 
+                                       "type boo = T<$",
+            expectedPos = 11,
+            addtlRefAssy = [System.IO.Path.Combine(System.Environment.CurrentDirectory,@"UnitTestsResources\MockTypeProviders\DummyProviderForLanguageServiceTesting.dll")])
+ 
+    [<Test>]
+    [<Category("TypeProvider")>]
+    [<Category("TypeProvider.StaticParameters")>]
+    //This test verifies that no ParamInfo in a string for a provided type  that exposes static parameter that takes >1 argument works normally.
+     //The intent here to make sure the ParamInfo is not shown when inside a string
+    member public this.``TypeProvider.Type.Negative.InString`` () =
+        this.TestParameterInfoNegative("type boo = \"N1.T<$\"",
+            addtlRefAssy = [System.IO.Path.Combine(System.Environment.CurrentDirectory,@"UnitTestsResources\MockTypeProviders\DummyProviderForLanguageServiceTesting.dll")])
+    
+    [<Test>]
+    [<Category("TypeProvider")>]
+    [<Category("TypeProvider.StaticParameters")>]
+    //This test verifies that no ParamInfo in a Comment for a provided type that exposes static parameter that takes >1 argument works normally.
+    //The intent here to make sure the ParamInfo is not shown when inside a comment
+    member public this.``TypeProvider.Type.Negative.InComment`` () =
+        this.TestParameterInfoNegative("// type boo = N1.T<$",
+            addtlRefAssy = [System.IO.Path.Combine(System.Environment.CurrentDirectory,@"UnitTestsResources\MockTypeProviders\DummyProviderForLanguageServiceTesting.dll")])
+ 
+
+ // Following are tricky:
+    // if we can't find end of the identifier on the current line, 
+    // we *must* look at the previous line to find the location where NameRes info ends
+    // so in these cases we can find the identifier and location of tooltip is beginning of it
+    // (but in general, we don't search for it)
+    [<Test>]
+    member public this.``Single.Locations.Multiline.IdentOnPrevLineWithGenerics``() =
+        this.TestParameterInfoLocation("let d = Dictionary<_, option< int >>  \n" +
+                                       "                ( $  )", 8) // on the "D" (line untestable)
+
+    [<Test>]
+    member public this.``Single.Locations.Multiline.IdentOnPrevLine``() =
+        this.TestParameterInfoLocation("do Console.WriteLine\n" + 
+                                       "        ($\"Multiline\")", 3)
+    [<Test>]
+    member public this.``Single.Locations.Multiline.IdentOnPrevPrevLine``() =
+        this.TestParameterInfoLocation("do Console.WriteLine\n" + 
+                                       "        (  \n" +
+                                       "          $ \"Multiline\")", 3)
+             
+    [<Test>]
+    member public this.``Single.Locations.GenericCtorWithoutNew``() =
+        this.TestParameterInfoLocation("let d = System.Collections.Generic.Dictionary<_, option< int >>   ( $ )", 8) // on "S" - standard 
+
+    [<Test>]
+    member public this.``Single.Locations.Multiline.GenericTyargsOnTheSameLine``() =
+        this.TestParameterInfoLocation("let dict3 = System.Collections.Generic.Dictionary<_, \n" +
+                                       "                option< int>>( $ )", 12) // on "S" (beginning of "System")
+    [<Test>]
+    member public this.``Single.Locations.Multiline.LongIdentSplit``() =
+        this.TestParameterInfoLocation("let ll = new System.Collections.\n" +
+                                       "                    Generic.List< _ > ($)", 13) // on "S" (beginning of "System")
+
+    [<Test>]
+    member public this.``Single.Locations.OperatorTrick3``() =
+        this.TestParameterInfoLocation
+            ("let mutable n = null\n" + 
+             "let aaa = Interlocked.Exchange<obj>(&n$, new obj())", 10) // "I" of Interlocked
+          
+    // A several cases that are tricky and we don't want to show anything
+    // in the following cases, we may return a location of an operator (its ambigous), but we don't want to show info about it!
+    
+    [<Test>]
+    member public this.``Single.Negative.OperatorTrick1``() =
+        this.TestParameterInfoNegative
+            ("let fooo = 0\n" + 
+             "             >($ 1 )") // this may be end of a generic args specification
+                                       
+    [<Test>]
+    member public this.``Single.Negative.OperatorTrick2``() =
+        this.TestParameterInfoNegative
+            ("let fooo = 0\n" + 
+             "             <($ 1 )")
+
+    /// No intellisense in comments/strings!
+    [<Test>]
+    member public this.``Single.InString``() =        
+        this.TestParameterInfoNegative
+            ("let s = \"System.Console.WriteLine($)\"")
+
+    /// No intellisense in comments/strings!
+    [<Test>]
+    member public this.``Single.InComment``() =        
+        this.TestParameterInfoNegative
+            ("// System.Console.WriteLine($)")
+  
+    [<Test>]
+    member this.``Regression.LocationOfParams.AfterQuicklyTyping.Bug91373``() =        
+        let code = [ "let f x = x   "
+                     "let f1 y = y  "
+                     "let z = f(    " ]
+        let (_, _, file) = this.CreateSingleFileProject(code)
+        
+        TakeCoffeeBreak(this.VS)
+        let gpatcc = GlobalParseAndTypeCheckCounter.StartNew(this.VS)
+
+        // In this case, we quickly type "f1(" and then see what parameter info would pop up.
+        // This simulates the case when the user quickly types after the file has been TCed before.
+        ReplaceFileInMemoryWithoutCoffeeBreak file (
+                   [ "let f x = x   "
+                     "let f1 y = y  "
+                     "let z = f(f1( " ] )
+        MoveCursorToEndOfMarker(file, "f1(")
+        // Note: no TakeCoffeeBreak(this.VS)
+        let info = GetParameterInfoAtCursorNoFallback file  // the 'NoFallback' version will not use the name environment, only captured name resolutions at specific locations
+        AssertEqual(null, info)
+        let info = GetParameterInfoAtCursor file // this will fall back to using the name environment, which is stale, but sufficient to look up the call to 'f1'
+        AssertEqual("f1", info.GetName(0))
+        // note about (6,1): for silly implementation reasons, we always report location of 'end of file' as first the char, 3 lines past the last line of the file
+        AssertEqual([|(3,11);(3,13);(3,13);(6,1)|], info.GetNoteworthyParamInfoLocations())
+
+        // after typechecking catches up, then even NoFallback should find it
+        TakeCoffeeBreak(this.VS)
+        let info = GetParameterInfoAtCursorNoFallback file  // the 'NoFallback' version will not use the name environment, only captured name resolutions at specific locations
+        AssertEqual("f1", info.GetName(0))
+        AssertEqual([|(3,11);(3,13);(3,13);(6,1)|], info.GetNoteworthyParamInfoLocations())
+        gpatcc.AssertExactly(0,0)
+
+    [<Test>]
+    member this.``LocationOfParams.AfterQuicklyTyping.CallConstructor``() =        
+        let code = [ "type Foo() = class end" ]
+        let (_, _, file) = this.CreateSingleFileProject(code)
+        
+        TakeCoffeeBreak(this.VS)
+        let gpatcc = GlobalParseAndTypeCheckCounter.StartNew(this.VS)
+
+        // In this case, we quickly type "new Foo(" and then see what parameter info would pop up.
+        // This simulates the case when the user quickly types after the file has been TCed before.
+        ReplaceFileInMemoryWithoutCoffeeBreak file (
+                   [ "type Foo() = class end"
+                     "let foo = new Foo(    " ] )
+        MoveCursorToEndOfMarker(file, "new Foo(")
+        // Note: no TakeCoffeeBreak(this.VS)
+        let info = GetParameterInfoAtCursorNoFallback file  // the 'NoFallback' version will not use the name environment, only captured name resolutions at specific locations
+        AssertEqual(null, info)
+        let info = GetParameterInfoAtCursor file // this will fall back to using the name environment, which is stale, but sufficient to look up the call to 'f1'
+        AssertEqual("Foo", info.GetName(0))
+        // note about (5,1): for silly implementation reasons, we always report location of 'end of file' as first the char, 3 lines past the last line of the file
+        AssertEqual([|(2,15);(2,18);(2,18);(5,1)|], info.GetNoteworthyParamInfoLocations())
+
+        // after typechecking catches up, then even NoFallback should find it
+        TakeCoffeeBreak(this.VS)
+        let info = GetParameterInfoAtCursorNoFallback file  // the 'NoFallback' version will not use the name environment, only captured name resolutions at specific locations
+        AssertEqual("Foo", info.GetName(0))
+        AssertEqual([|(2,15);(2,18);(2,18);(5,1)|], info.GetNoteworthyParamInfoLocations())
+        gpatcc.AssertExactly(0,0)
+
+(*
+This does not currently work, because the 'fallback to name environment' does weird QuickParse-ing and mangled the long id "Bar.Foo".
+We really need to rewrite some code paths here to use the real parse tree rather than QuickParse-ing.
+    [<Test>]
+    member this.``ParameterInfo.LocationOfParams.AfterQuicklyTyping.CallConstructorViaLongId.Bug94333``() =        
+        let solution = CreateSolution(this.VS)
+        let project = CreateProject(solution,"testproject")
+        let code = [ "module Bar = type Foo() = class end" ]
+        let file = AddFileFromText(project,"File1.fs", code)
+        let file = OpenFile(project,"File1.fs")
+        
+        TakeCoffeeBreak(this.VS)
+        let gpatcc = GlobalParseAndTypeCheckCounter.StartNew(this.VS)
+
+        // In this case, we quickly type "new Foo(" and then see what parameter info would pop up.
+        // This simulates the case when the user quickly types after the file has been TCed before.
+        ReplaceFileInMemoryWithoutCoffeeBreak file (
+                   [ "module Bar = type Foo() = class end"
+                     "let foo = new Bar.Foo(    " ] )
+        MoveCursorToEndOfMarker(file, "new Bar.Foo(")
+        // Note: no TakeCoffeeBreak(this.VS)
+        let info = GetParameterInfoAtCursorNoFallback file  // the 'NoFallback' version will not use the name environment, only captured name resolutions at specific locations
+        AssertEqual(null, info)
+        let info = GetParameterInfoAtCursor file // this will fall back to using the name environment, which is stale, but sufficient to look up the call to 'f1'
+        AssertEqual("Foo", info.GetName(0))
+        // note about (5,1): for silly implementation reasons, we always report location of 'end of file' as first the char, 3 lines past the last line of the file
+        AssertEqual([|(2,15);(2,22);(2,22);(5,1)|], info.GetNoteworthyParamInfoLocations())
+
+        // after typechecking catches up, then even NoFallback should find it
+        TakeCoffeeBreak(this.VS)
+        let info = GetParameterInfoAtCursorNoFallback file  // the 'NoFallback' version will not use the name environment, only captured name resolutions at specific locations
+        AssertEqual("Foo", info.GetName(0))
+        AssertEqual([|(2,15);(2,22);(2,22);(5,1)|], info.GetNoteworthyParamInfoLocations())
+        gpatcc.AssertExactly(0,0)
+*)
+
+    [<Test>]
+    member public this.``ParameterInfo.NamesOfParams``() =
+        let testLines = [
+            "type Foo ="
+            "    static member F(a:int, b:bool, c:int, d:int, ?e:int) = ()"
+            "let a = 42"
+            "Foo.F(0,(a=42),d=3,?e=Some 4,c=2)"
+            "// names are _,_,d,e,c" ]
+        let (_, _, file) = this.CreateSingleFileProject(testLines)
+        MoveCursorToStartOfMarker(file, "0")
+        let info = GetParameterInfoAtCursor file
+        let names = info.GetParameterNames()
+        AssertEqual([| null; null; "d"; "e"; "c" |], names)
+
+    // $ is the location of the cursor/caret
+    // ^ marks all of these expected points:
+    //     - start of the long id that is the method call containing the caret
+    //     - end of the long id that is the method call containing the caret
+    //     - open paren of the method call (or first char of arg expression if no open paren)
+    //     - for every param, end of expr that is the param (or closeparen if no params (unit))
+    member public this.TestParameterInfoLocationOfParams (testLine, ?markAtEOF, ?additionalReferenceAssemblies) =
+        let cursorPrefix, testLines = this.ExtractLineInfo testLine
+        let testLinesAndLocs = testLines |> List.mapi (fun i s ->
+            let r = new System.Text.StringBuilder(s)
+            let locs = 
+                [while r.ToString().IndexOf('^') <> -1 do
+                    let c = r.ToString().IndexOf('^')
+                    r.Remove(c,1) |> ignore
+                    yield (i+1,c+1)]
+            r.ToString(), locs)
+        let testLines = testLinesAndLocs |> List.map fst
+        let expectedLocs = testLinesAndLocs |> List.map snd |> List.collect id |> List.toArray 
+        // note: for silly implementation reasons, we always report location of 'end of file' as first the char, 3 lines past the last line of the file
+        let expectedLocs = if defaultArg markAtEOF false then 
+                                Array.append expectedLocs [| testLines.Length+3, 1 |] 
+                           else 
+                                expectedLocs
+        let cursorPrefix = cursorPrefix.Replace("^","")
+
+        let references = "System.Core"::(defaultArg additionalReferenceAssemblies [])
+        let (_, _, file) = this.CreateSingleFileProject(testLines, references = references)
+        MoveCursorToEndOfMarker(file, cursorPrefix)
+        let info = GetParameterInfoAtCursor file
+        if info=null then raise NoParamInfo
+        AssertEqual(expectedLocs, info.GetNoteworthyParamInfoLocations()) 
+
+    [<Test>]
+    member public this.``LocationOfParams.Case1``() =        
+        this.TestParameterInfoLocationOfParams("""^System.Console.WriteLine^^("hel$lo"^)""")
+
+    [<Test>]
+    member public this.``LocationOfParams.Case2``() =        
+        this.TestParameterInfoLocationOfParams("""^System.Console.WriteLine^   ^(  "hel$lo {0}"  ^, "Brian" ^)""")
+
+    [<Test>]
+    member public this.``LocationOfParams.Case3``() =        
+        this.TestParameterInfoLocationOfParams(
+            """^System.Console.WriteLine^  
+                 ^(  
+                        "hel$lo {0}"  ^, 
+                        "Brian" ^)  """)
+
+    [<Test>]
+    member public this.``LocationOfParams.Case4``() =        
+        this.TestParameterInfoLocationOfParams("""^System.Console.WriteLine^   ^(  "hello {0}"  ^, ("tuples","don't $ confuse it") ^)""")
+
+    [<Test>]
+    member public this.``ParameterInfo.LocationOfParams.Bug112688``() =
+        let testLines = [
+            "let f x y = ()"
+            "module MailboxProcessorBasicTests ="
+            "    do f 0"
+            "         0"
+            "    let zz = 42"
+            "    for timeout in [0; 10] do" 
+            "      ()" ]
+        let (_,_, file) = this.CreateSingleFileProject(testLines)
+        MoveCursorToStartOfMarker(file, "let zz")
+        // in the bug, this caused an assert to fire
+        let info = GetParameterInfoAtCursor file
+        ()
+
+    [<Test>]
+    member public this.``ParameterInfo.LocationOfParams.Bug112340``() =
+        let testLines = [
+            """let a = typeof<N."""
+            """printfn "%A" a""" ]
+        let (_,_, file) = this.CreateSingleFileProject(testLines)
+        MoveCursorToStartOfMarker(file, "printfn")
+        // in the bug, this caused an assert to fire
+        let info = GetParameterInfoAtCursor file
+        ()
+
+    [<Test>]
+    member public this.``Regression.LocationOfParams.Bug91479``() =        
+        this.TestParameterInfoLocationOfParams("""let z = fun x -> x + ^System.Int16.Parse^^($ """, markAtEOF=true)
+
+    [<Test>]
+    member public this.``LocationOfParams.Attributes.Bug230393``() =        
+        this.TestParameterInfoLocationOfParams("""
+            let paramTest((strA : string),(strB : string)) =
+                strA + strB
+            ^paramTest^^( $ 
+ 
+            [<^Measure>]
+            type RMB
+        """)
+
+    [<Test>]
+    member public this.``LocationOfParams.InfixOperators.Case1``() =        
+        // infix operators like '+' do not give their own param info
+        this.TestParameterInfoLocationOfParams("""^System.Console.WriteLine^^("" + "$"^)""")
+
+    [<Test>]
+    member public this.``LocationOfParams.InfixOperators.Case2``() =        
+        // infix operators like '+' do give param info when used as prefix ops
+        this.TestParameterInfoLocationOfParams("""System.Console.WriteLine((^+^)^($3^)(4))""")
+
+    [<Test>]
+    member public this.``LocationOfParams.GenericMethodExplicitTypeArgs()``() =        
+        this.TestParameterInfoLocationOfParams("""
+            type T<'a> =
+                static member M(x:int, y:string) = x + y.Length
+            let x = ^T<int>.M^^(1^, $"test"^)    """)
+
+    [<Test>]
+    member public this.``LocationOfParams.InsideAMemberOfAType``() =        
+        this.TestParameterInfoLocationOfParams("""
+            type Widget(z) = 
+                member x.a = (1 <> ^System.Int32.Parse^^("$"^)) """)
+
+    [<Test>]
+    member public this.``LocationOfParams.InsidePropertyGettersAndSetters.Case1``() =        
+        this.TestParameterInfoLocationOfParams("""
+            type Widget(z) = 
+                member x.P1 
+                    with get() = ^System.Int32.Parse^^("$"^)
+                    and set(z) = System.Int32.Parse("") |> ignore
+                member x.P2 with get() = System.Int32.Parse("")
+                member x.P2 with set(z) = System.Int32.Parse("") |> ignore """)
+
+    [<Test>]
+    member public this.``LocationOfParams.InsidePropertyGettersAndSetters.Case2``() =        
+        this.TestParameterInfoLocationOfParams("""
+            type Widget(z) = 
+                member x.P1 
+                    with get() = System.Int32.Parse("")
+                    and set(z) = ^System.Int32.Parse^^("$"^) |> ignore
+                member x.P2 with get() = System.Int32.Parse("")
+                member x.P2 with set(z) = System.Int32.Parse("") |> ignore """)
+
+    [<Test>]
+    member public this.``LocationOfParams.InsidePropertyGettersAndSetters.Case3``() =        
+        this.TestParameterInfoLocationOfParams("""
+            type Widget(z) = 
+                member x.P1 
+                    with get() = System.Int32.Parse("")
+                    and set(z) = System.Int32.Parse("") |> ignore
+                member x.P2 with get() = ^System.Int32.Parse^^("$"^)
+                member x.P2 with set(z) = System.Int32.Parse("") |> ignore """)
+
+    [<Test>]
+    member public this.``LocationOfParams.InsidePropertyGettersAndSetters.Case4``() =        
+        this.TestParameterInfoLocationOfParams("""
+            type Widget(z) = 
+                member x.P1 
+                    with get() = System.Int32.Parse("")
+                    and set(z) = System.Int32.Parse("") |> ignore
+                member x.P2 with get() = System.Int32.Parse("")
+                member x.P2 with set(z) = ^System.Int32.Parse^^("$"^) |> ignore """)
+
+    [<Test>]
+    member public this.``LocationOfParams.InsideObjectExpression``() =        
+        this.TestParameterInfoLocationOfParams("""
+                let _ = { new ^System.Object^^($^) with member __.GetHashCode() = 2}""")
+
+    [<Test>]
+    member public this.``LocationOfParams.Nested1``() =        
+        this.TestParameterInfoLocationOfParams("""System.Console.WriteLine("hello {0}"  , ^sin^  ^(4$2.0 ^) )""")
+
+
+    [<Test>]
+    member public this.``LocationOfParams.MatchGuard``() =        
+        this.TestParameterInfoLocationOfParams("""match [1] with | [x] when ^box^^($x^) <> null -> ()""")
+
+    [<Test>]
+    member public this.``LocationOfParams.Nested2``() =        
+        this.TestParameterInfoLocationOfParams("""System.Console.WriteLine("hello {0}"  , ^sin^  ^4$2.0^ )""")
+
+    [<Test>]
+    member public this.``LocationOfParams.Generics1``() =        
+        this.TestParameterInfoLocationOfParams("""
+            let f<'T,'U>(x:'T, y:'U) = (y,x)
+            let r = ^f^<int,string>^(4$2^,""^)""")
+
+    [<Test>]
+    member public this.``LocationOfParams.Generics2``() =        
+        this.TestParameterInfoLocationOfParams("""let x = ^System.Collections.Generic.Dictionary^<int,int>^(42^,n$ull^)""")
+
+    [<Test>]
+    member public this.``LocationOfParams.Unions1``() =        
+        this.TestParameterInfoLocationOfParams("""
+            type MyDU =
+                | FOO of int * string
+            let r = ^FOO^^(42^,"$"^) """)
+
+    [<Test>]
+    member public this.``LocationOfParams.EvenWhenOverloadResolutionFails.Case1``() =        
+        this.TestParameterInfoLocationOfParams("""let a = new ^System.IO.FileStream^^($^)""")
+
+    [<Test>]
+    member public this.``LocationOfParams.EvenWhenOverloadResolutionFails.Case2``() =        
+        this.TestParameterInfoLocationOfParams("""
+            open System.Collections.Generic
+            open System.Linq
+            let l = List<int>([||])
+            ^l.Aggregate^^($^) // was once a bug""")
+
+    [<Test>]
+    member public this.``LocationOfParams.BY_DESIGN.WayThatMismatchedParensFailOver.Case1``() =        
+        // when only one 'statement' after the mismatched parens after a comma, the comma swallows it and it becomes a badly-indented
+        // continuation of the expression from the previous line
+        this.TestParameterInfoLocationOfParams("""
+            type CC() =
+                member this.M(a,b,c,d) = a+b+c+d
+            let c = new CC()
+            ^c.M^^(1^,2^,3^, $
+            c.M(1,2,3,4)""", markAtEOF=true)
+
+    [<Test>]
+    member public this.``LocationOfParams.BY_DESIGN.WayThatMismatchedParensFailOver.Case2``() =        
+        // when multiple 'statements' after the mismatched parens after a comma, the parser sees a single argument to the method that
+        // is a statement sequence, e.g. a bunch of discarded expressions.  That is, 
+        //     c.M(1,2,3,
+        //     c.M(1,2,3,4)
+        //     c.M(1,2,3,4)
+        //     c.M(1,2,3,4)
+        // is like
+        //     c.M(let r = 1,2,3,
+        //                     c.M(1,2,3,4)
+        //                 c.M(1,2,3,4)
+        //                 c.M(1,2,3,4)
+        //         in r)
+        this.TestParameterInfoLocationOfParams("""
+            type CC() =
+                member this.M(a,b,c,d) = a+b+c+d
+            let c = new CC()
+            ^c.M^^(1,2,3, $
+            c.M(1,2,3,4)
+            c.M(1,2,3,4)
+            c.M(1,2,3,4)""", markAtEOF=true)
+
+    [<Test>]
+    member public this.``LocationOfParams.Tuples.Bug91360.Case1``() =        
+        this.TestParameterInfoLocationOfParams("""
+            ^System.Console.WriteLine^^( (4$2,43) ^) // oops""")
+
+    [<Test>]
+    member public this.``LocationOfParams.Tuples.Bug91360.Case2``() =        
+        this.TestParameterInfoLocationOfParams("""
+            ^System.Console.WriteLine^^( $(42,43) ^) // oops""")
+
+    [<Test>]
+    member public this.``LocationOfParams.Tuples.Bug123219``() =
+        this.TestParameterInfoLocationOfParams("""
+            type Expr = | Num of int
+            type T<'a>() = 
+                member this.M1(a:int*string, b:'a -> unit) = ()
+            let x = new T<Expr>()
+ 
+            ^x.M1^^((1,$ """, markAtEOF=true)
+
+    [<Test>]
+    member public this.``LocationOfParams.UnmatchedParens.Bug91609.OtherCases.Open``() =        
+        this.TestParameterInfoLocationOfParams("""
+            let arr = Array.create 4 1
+            arr.[1] <- ^System.Int32.Parse^^($
+            open^ System""")
+
+    [<Test>]
+    member public this.``LocationOfParams.UnmatchedParens.Bug91609.OtherCases.Module``() =        
+        this.TestParameterInfoLocationOfParams("""
+            let arr = Array.create 4 1
+            arr.[1] <- ^System.Int32.Parse^^($
+            ^module Foo =
+                let x = 42""")
+
+    [<Test>]
+    member public this.``LocationOfParams.UnmatchedParens.Bug91609.OtherCases.Namespace``() =        
+        this.TestParameterInfoLocationOfParams("""
+            namespace Foo
+            module Bar =
+                let arr = Array.create 4 1
+                arr.[1] <- ^System.Int32.Parse^^($
+            namespace^ Other""")
+
+    [<Test>]
+    member public this.``LocationOfParams.UnmatchedParens.Bug91609.Ok``() =        
+        this.TestParameterInfoLocationOfParams("""
+            let arr = Array.create 4 1
+            arr.[1] <- ^System.Int32.Parse^^($
+            let squares3 = () 
+            ^type Expr = class end
+            let rec Evaluate (env:Map<string,int>) exp = ()""")
+
+    [<Test>]
+    member public this.``LocationOfParams.UnmatchedParens.Bug91609.AlsoOk``() =        
+        this.TestParameterInfoLocationOfParams("""
+            let arr = Array.create 4 1
+            arr.[1] <- System.Int32.Parse(int(int(int(^int^^($
+            let squares3 = () 
+            ^type Expr = class end
+            let rec Evaluate (env:Map<string,int>) exp = ()""")
+
+    [<Test>]
+    member public this.``LocationOfParams.UnmatchedParens.Bug91609.NowGood``() =        
+        // This case originally failed, by Design, as there is a finite limit to how many unmatched parens we can handle before the parser gives up and fails catastrophically.
+        // However now that we recover from more kinds of tokens, e.g. OBLOCKEND, we can easily go much much deeper, and so this case (and most practical cases) now succeeds.
+        this.TestParameterInfoLocationOfParams("""
+            let arr = Array.create 4 1
+            arr.[1] <- System.Int32.Parse(int(int(int(int(int(int(^int^^($
+            let squares3 = () 
+            ^type Expr = class end
+            let rec Evaluate (env:Map<string,int>) exp = ()""")
+
+    [<Test>]
+    member public this.``LocationOfParams.UnmatchedParens.Bug150492.Case1``() =        
+        this.TestParameterInfoLocationOfParams("""
+            module Inner =
+                ^System.Console.Write^^($
+                let y = 4 
+            ^type Foo() = inherit obj()
+            [<assembly:System.Security.AllowPartiallyTrustedCallersAttribute>]
+            do () """)
+
+    [<Test>]
+    member public this.``LocationOfParams.UnmatchedParens.Bug150492.Case2``() =        
+        // like previous test, but with explicit begin-end at module
+        this.TestParameterInfoLocationOfParams("""
+            module Inner = begin
+                ^System.Console.Write^^($
+                let y = 4 
+            ^end
+            type Foo() = inherit obj()
+            [<assembly:System.Security.AllowPartiallyTrustedCallersAttribute>]
+            do () """)
+
+    [<Test>]
+    member public this.``LocationOfParams.UnmatchedParens.Bug150492.Case1.WhenExtraModule``() =        
+        this.TestParameterInfoLocationOfParams("""
+            module Program
+            let xxx = 42
+            type FooBaz() = class end
+            module Inner =
+                ^System.Console.Write^^($
+                let y = 4 
+            ^type Foo() = inherit obj()
+            [<assembly:System.Security.AllowPartiallyTrustedCallersAttribute>]
+            do () """)
+
+    [<Test>]
+    member public this.``LocationOfParams.UnmatchedParens.Bug150492.Case2.OkWhenExtraModule``() =        
+        // like previous test, but with explicit begin-end at module
+        this.TestParameterInfoLocationOfParams("""
+            module Program
+            let xxx = 42
+            type FooBaz() = class end
+            module Inner = begin
+                ^System.Console.Write^^($
+                let y = 4 
+            ^end
+            type Foo() = inherit obj()
+            [<assembly:System.Security.AllowPartiallyTrustedCallersAttribute>]
+            do () """)
+
+    [<Test>]
+    member this.``LocationOfParams.InheritsClause.Bug192134``() =        
+        this.TestParameterInfoLocationOfParams("""
+            type B(x : int) = 
+               new(x1:int, x2: int) = new B(10)
+            type A() =
+               inherit ^B^^(1$^,2^)""")
+
+    [<Test>]
+    member public this.``LocationOfParams.ThisOnceAsserted``() =        
+        try
+            this.TestParameterInfoLocationOfParams("""
+                module CSVTypeProvider
+
+                f(fun x ->
+                    match args with
+                    | [| y |] -> 
+                        for name, kind in (headerNames,
+                        rowType.AddMember(new ^ProvidedProperty^^($
+                        null                       
+                    | _ -> failwith "unexpected generic params" )
+
+                let rec emitRegKeyNamedType (container:TypeContainer) (typeName:string) (key:RegistryKey) =         
+                    let keyType = 0
+                    keyType
+
+                match types |> Array.tryFind (fun ty -> ty.Name = typeName^) with _ -> ()""")
+        with
+            | NoParamInfo -> () // expect there not to be any param info because parser failed
+
+    [<Test>]
+    member public this.``LocationOfParams.ThisOnceAssertedToo``() =        
+        try
+            this.TestParameterInfoLocationOfParams("""
+                let readString() =
+                    let x = 42
+                    while ('"' = '""' then
+                            () 
+                        else
+                            let sb = new System.Text.StringBuilder()
+                            while true do
+                                ($)  """)
+        with
+            | NoParamInfo -> () // expect there not to be any param info because parser failed
+
+    [<Test>]
+    member public this.``LocationOfParams.UnmatchedParensBeforeModuleKeyword.Bug245850.Case1a``() =        
+        this.TestParameterInfoLocationOfParams("""
+            module Repro =
+                for a in ^System.Int16.TryParse^^($  
+            ^module AA = 
+                let x = 10 """)
+
+    [<Test>]
+    member public this.``LocationOfParams.UnmatchedParensBeforeModuleKeyword.Bug245850.Case1b``() =        
+        this.TestParameterInfoLocationOfParams("""
+            module Repro =
+                for a in ^System.Int16.TryParse^^("4$2"  
+            ^module AA = 
+                let x = 10 """)
+
+    [<Test>]
+    member public this.``LocationOfParams.UnmatchedParensBeforeModuleKeyword.Bug245850.Case1c``() =        
+        this.TestParameterInfoLocationOfParams("""
+            module Repro =
+                for a in ^System.Int16.TryParse^^("4$2"^,  
+            ^module AA = 
+                let x = 10 """)
+
+    [<Test>]
+    member public this.``LocationOfParams.UnmatchedParensBeforeModuleKeyword.Bug245850.Case2a``() =        
+        this.TestParameterInfoLocationOfParams("""
+            module Repro =
+                query { for a in ^System.Int16.TryParse^^($   
+            ^module AA = 
+                let x = 10 """)
+
+    [<Test>]
+    member public this.``LocationOfParams.UnmatchedParensBeforeModuleKeyword.Bug245850.Case2b``() =        
+        this.TestParameterInfoLocationOfParams("""
+            module Repro =
+                query { for a in ^System.Int16.TryParse^^("4$2"  
+            ^module AA = 
+                let x = 10 """)
+
+    [<Test>]
+    member public this.``LocationOfParams.UnmatchedParensBeforeModuleKeyword.Bug245850.Case2c``() =        
+        this.TestParameterInfoLocationOfParams("""
+            module Repro =
+                query { for a in ^System.Int16.TryParse^^("4$2"^,  
+            ^module AA = 
+                let x = 10 """)
+
+    [<Test>]
+    member public this.``LocationOfParams.QueryCustomOperation.Bug222128``() =        
+        this.TestParameterInfoLocationOfParams("""
+            type T() =
+                 member x.GetCollection() = [1;2;3;4]
+            let q2 = query {
+               for e in T().GetCollection() do
+                 where (e > 250)
+                 ^skip^^($  
+            ^} """)
+
+    [<Test>]
+    member public this.``LocationOfParams.QueryCurlies.Bug204150.Case1``() =        
+        this.TestParameterInfoLocationOfParams("""
+            type T() =
+                 member x.GetCollection() = [1;2;3;4]
+            open System.Linq
+            let q6 =
+                  query {
+                    for E in ^T().GetCollection().Aggregate^^($
+                  ^} """)
+
+    [<Test>]
+    member public this.``LocationOfParams.QueryCurlies.Bug204150.Case2``() =        
+        this.TestParameterInfoLocationOfParams("""
+            type T() =
+                 member x.GetCollection() = [1;2;3;4]
+            open System.Linq
+            let q6 =
+                  query {
+                    for E in ^T().GetCollection().Aggregate^^(42$
+                  ^} """)
+
+    [<Test>]
+    member public this.``LocationOfParams.QueryCurlies.Bug204150.Case3``() =        
+        this.TestParameterInfoLocationOfParams("""
+            type T() =
+                 member x.GetCollection() = [1;2;3;4]
+            open System.Linq
+            let q6 =
+                  query {
+                    for E in ^T().GetCollection().Aggregate^^(42^,$
+                  ^} """)
+
+    [<Test>]
+    member public this.``LocationOfParams.QueryCurlies.Bug204150.Case4``() =        
+        this.TestParameterInfoLocationOfParams("""
+            type T() =
+                 member x.GetCollection() = [1;2;3;4]
+            open System.Linq
+            let q6 =
+                  query {
+                    for E in ^T().GetCollection().Aggregate^^(42^, 43$
+                  ^} """)
+
+    (* Tests for type provider static argument parameterinfos ------------------------------------------ *)
+
+    member public this.TestParameterInfoLocationOfParamsWithVariousSurroundingContexts (testLine:string, ?markAtEnd, ?additionalReferenceAssemblies) =
+        let numSpacesOfIndent =
+            let lines = testLine.Split[|'\n'|]
+            let firstLineWithText = lines |> Array.find (fun s -> s |> Seq.exists (fun c -> not(Char.IsWhiteSpace c)))
+            firstLineWithText |> Seq.findIndex (fun c -> not(Char.IsWhiteSpace c))
+        let indent = String.replicate numSpacesOfIndent " "
+        let contexts = [
+            false, ""
+            true,  "namespace Foo"
+            false, "module Program"
+            ]
+        let prefixes = [
+            true,  ""
+            false, "let x = 42"
+            false, "let f x = 42"
+            true,  "type MyClass() = class end"
+            ]
+        let suffixes = [
+            true,  ""
+            false, "let x = 42"
+            false, "let f x = 42"
+            true,  "type MyClass2() = class end"
+            true,  "module M = begin end"
+            //true,  "namespace Bar"  // TODO only legal to test this if already in a namespace
+            ]
+        for isNamespace, startText in contexts do
+        for p in prefixes |> List.filter (fun (okInNS,_) -> if isNamespace then okInNS else true) |> List.map snd do
+        for s in suffixes |> List.filter (fun (okInNS,_) -> if isNamespace then okInNS else true) |> List.map snd do
+        (
+            let needMarkAtEnd = defaultArg markAtEnd false
+            let s, needMarkAtEnd =
+                if needMarkAtEnd && s<>"" then
+                    "^"+s, false
+                else
+                    s, needMarkAtEnd
+            let allText = indent + startText + Environment.NewLine 
+                        + indent + p + Environment.NewLine 
+                        + testLine + Environment.NewLine 
+                        + indent + s
+            printfn "-----------------"
+            printfn "%s" allText
+            this.TestParameterInfoLocationOfParams (allText, markAtEOF=needMarkAtEnd, ?additionalReferenceAssemblies=additionalReferenceAssemblies)
+        )
+
+    [<Test>]
+    member public this.``LocationOfParams.TypeProviders.Basic``() =        
+        this.TestParameterInfoLocationOfParamsWithVariousSurroundingContexts("""
+            type U = ^N1.T^^< "fo$o"^, 42 ^>""", 
+            additionalReferenceAssemblies = [System.IO.Path.Combine(System.Environment.CurrentDirectory,@"UnitTestsResources\MockTypeProviders\DummyProviderForLanguageServiceTesting.dll")])
+
+    [<Test>]
+    member public this.``LocationOfParams.TypeProviders.BasicNamed``() =        
+        this.TestParameterInfoLocationOfParamsWithVariousSurroundingContexts("""
+            type U = ^N1.T^^< "fo$o"^, ParamIgnored=42 ^>""", 
+            additionalReferenceAssemblies = [System.IO.Path.Combine(System.Environment.CurrentDirectory,@"UnitTestsResources\MockTypeProviders\DummyProviderForLanguageServiceTesting.dll")])
+
+
+    [<Test>]
+    member public this.``LocationOfParams.TypeProviders.Prefix0``() =        
+        this.TestParameterInfoLocationOfParamsWithVariousSurroundingContexts("""
+            type U = ^N1.T^^< $ """, // missing all params, just have <
+            markAtEnd = true,
+            additionalReferenceAssemblies = [System.IO.Path.Combine(System.Environment.CurrentDirectory,@"UnitTestsResources\MockTypeProviders\DummyProviderForLanguageServiceTesting.dll")])
+
+    [<Test>]
+    member public this.``LocationOfParams.TypeProviders.Prefix1``() =        
+        this.TestParameterInfoLocationOfParamsWithVariousSurroundingContexts("""
+            type U = ^N1.T^^< "fo$o"^, 42 """, // missing >
+            markAtEnd = true,
+            additionalReferenceAssemblies = [System.IO.Path.Combine(System.Environment.CurrentDirectory,@"UnitTestsResources\MockTypeProviders\DummyProviderForLanguageServiceTesting.dll")])
+
+    [<Test>]
+    member public this.``LocationOfParams.TypeProviders.Prefix1Named``() =        
+        this.TestParameterInfoLocationOfParamsWithVariousSurroundingContexts("""
+            type U = ^N1.T^^< "fo$o"^, ParamIgnored=42 """, // missing >
+            markAtEnd = true,
+            additionalReferenceAssemblies = [System.IO.Path.Combine(System.Environment.CurrentDirectory,@"UnitTestsResources\MockTypeProviders\DummyProviderForLanguageServiceTesting.dll")])
+
+    [<Test>]
+    member public this.``LocationOfParams.TypeProviders.Prefix2``() =        
+        this.TestParameterInfoLocationOfParamsWithVariousSurroundingContexts("""
+            type U = ^N1.T^^< "fo$o"^, """, // missing last param
+            markAtEnd = true,
+            additionalReferenceAssemblies = [System.IO.Path.Combine(System.Environment.CurrentDirectory,@"UnitTestsResources\MockTypeProviders\DummyProviderForLanguageServiceTesting.dll")])
+
+    [<Test>]
+    member public this.``LocationOfParams.TypeProviders.Prefix2Named1``() =        
+        this.TestParameterInfoLocationOfParamsWithVariousSurroundingContexts("""
+            type U = ^N1.T^^< "fo$o"^, ParamIgnored= """, // missing last param after name with equals
+            markAtEnd = true,
+            additionalReferenceAssemblies = [System.IO.Path.Combine(System.Environment.CurrentDirectory,@"UnitTestsResources\MockTypeProviders\DummyProviderForLanguageServiceTesting.dll")])
+
+    [<Test>]
+    member public this.``LocationOfParams.TypeProviders.Prefix2Named2``() =        
+        this.TestParameterInfoLocationOfParamsWithVariousSurroundingContexts("""
+            type U = ^N1.T^^< "fo$o"^, ParamIgnored """, // missing last param after name sans equals
+            markAtEnd = true,
+            additionalReferenceAssemblies = [System.IO.Path.Combine(System.Environment.CurrentDirectory,@"UnitTestsResources\MockTypeProviders\DummyProviderForLanguageServiceTesting.dll")])
+
+    [<Test>]
+    member public this.``LocationOfParams.TypeProviders.Negative1``() =       
+        try 
+            this.TestParameterInfoLocationOfParamsWithVariousSurroundingContexts("""
+                type D = ^System.Collections.Generic.Dictionary^^< in$t, int ^>""")
+            failwith "unexpected param info for generic type"
+        with
+        | :? NoParamInfo -> ()
+
+    [<Test>]
+    member public this.``LocationOfParams.TypeProviders.Negative2``() =       
+        try 
+            this.TestParameterInfoLocationOfParamsWithVariousSurroundingContexts("""
+                type D = ^System.Collections.Generic.List^^< in$t ^>""")
+            failwith "unexpected param info for generic type"
+        with
+        | :? NoParamInfo -> ()
+
+    [<Test>]
+    member public this.``LocationOfParams.TypeProviders.Negative3``() =       
+        try 
+            this.TestParameterInfoLocationOfParams("""
+                let i = 42
+                let b = ^i^^< 4$2""")
+            failwith "unexpected param info for generic type"
+        with
+        | :? NoParamInfo -> ()
+
+    [<Test>]
+    member public this.``LocationOfParams.TypeProviders.Negative4.Bug181000``() =       
+        try 
+            this.TestParameterInfoLocationOfParamsWithVariousSurroundingContexts("""
+                type U = ^N1.T^^< "foo"^, 42 ^>$  """,   // when the caret is right of the '>', we should not report any param info
+                additionalReferenceAssemblies = [System.IO.Path.Combine(System.Environment.CurrentDirectory,@"UnitTestsResources\MockTypeProviders\DummyProviderForLanguageServiceTesting.dll")])
+            failwith "unexpected param info for generic type"
+        with
+        | :? NoParamInfo -> ()
+
+    [<Test>]
+    member public this.``LocationOfParams.TypeProviders.BasicWithinExpr``() =        
+        this.TestParameterInfoLocationOfParams("""
+            let f() =
+                let r = id( ^N1.T^^< "fo$o"^, ParamIgnored=42 ^> )
+                r    """, 
+            additionalReferenceAssemblies = [System.IO.Path.Combine(System.Environment.CurrentDirectory,@"UnitTestsResources\MockTypeProviders\DummyProviderForLanguageServiceTesting.dll")])
+
+    [<Test>]
+    member public this.``LocationOfParams.TypeProviders.BasicWithinExpr.DoesNotInterfereWithOuterFunction``() =        
+        this.TestParameterInfoLocationOfParams("""
+            let f() =
+                let r = ^id^^( N1.$T< "foo", ParamIgnored=42 > ^)
+                r    """, 
+            additionalReferenceAssemblies = [System.IO.Path.Combine(System.Environment.CurrentDirectory,@"UnitTestsResources\MockTypeProviders\DummyProviderForLanguageServiceTesting.dll")])
+
+    [<Test>]
+    member public this.``LocationOfParams.TypeProviders.Bug199744.ExcessCommasShouldNotAssertAndShouldGiveInfo.Case1``() =        
+        this.TestParameterInfoLocationOfParamsWithVariousSurroundingContexts("""
+            type U = ^N1.T^^< "fo$o"^, 42^, ^, ^>""", 
+            additionalReferenceAssemblies = [System.IO.Path.Combine(System.Environment.CurrentDirectory,@"UnitTestsResources\MockTypeProviders\DummyProviderForLanguageServiceTesting.dll")])
+
+    [<Test>]
+    member public this.``LocationOfParams.TypeProviders.Bug199744.ExcessCommasShouldNotAssertAndShouldGiveInfo.Case2``() =        
+        this.TestParameterInfoLocationOfParamsWithVariousSurroundingContexts("""
+            type U = ^N1.T^^< "fo$o"^, ^, ^>""", 
+            additionalReferenceAssemblies = [System.IO.Path.Combine(System.Environment.CurrentDirectory,@"UnitTestsResources\MockTypeProviders\DummyProviderForLanguageServiceTesting.dll")])
+
+    [<Test>]
+    member public this.``LocationOfParams.TypeProviders.Bug199744.ExcessCommasShouldNotAssertAndShouldGiveInfo.Case3``() =        
+        this.TestParameterInfoLocationOfParamsWithVariousSurroundingContexts("""
+            type U = ^N1.T^^< ^,$ ^>""", 
+            additionalReferenceAssemblies = [System.IO.Path.Combine(System.Environment.CurrentDirectory,@"UnitTestsResources\MockTypeProviders\DummyProviderForLanguageServiceTesting.dll")])
+
+    [<Test>]
+    member public this.``TypeProvider.FormatOfNamesOfSystemTypes``() =
+        let code = ["""type TTT = N1.T< "foo", ParamIgnored=42 > """]
+        let references = [System.IO.Path.Combine(System.Environment.CurrentDirectory,@"UnitTestsResources\MockTypeProviders\DummyProviderForLanguageServiceTesting.dll")]
+        let (_, _, file) = this.CreateSingleFileProject(code, references = references)
+        let gpatcc = GlobalParseAndTypeCheckCounter.StartNew(this.VS)
+        MoveCursorToEndOfMarker(file,"foo")
+        let methodGroup = GetParameterInfoAtCursor file
+        let actualDisplays =
+            [ for i = 0 to methodGroup.GetCount() - 1 do
+                yield [ for j = 0 to methodGroup.GetParameterCount(i) - 1 do
+                            let (name,display,description) = methodGroup.GetParameterInfo(i,j) 
+                            yield display ] ]
+        let expected = [["Param1: string"; "ParamIgnored: int"]]  // key here is we want e.g. "int" and not "System.Int32"
+        AssertEqual(expected, actualDisplays)
+        gpatcc.AssertExactly(0,0)
+
+    [<Test>]
+    member public this.``ParameterNamesInFunctionsDefinedByLetBindings``() = 
+        let useCases = 
+            [
+                """
+                let foo (n1 : int) (n2 : int) = n1 + n2
+                foo(
+                """, "foo(", ["n1: int"]
+
+                """
+                let foo (n1 : int, n2 : int) = n1 + n2
+                foo(
+                """, "foo(", ["n1: int"; "n2: int"]
+
+                """
+                let foo (n1 : int, n2 : int) = n1 + n2
+                foo(2,
+                """, "foo(2,", ["n1: int"; "n2: int"]
+
+                (* Negative tests - display only types*)
+                """
+                let foo = List.map
+                foo(
+                """, "foo(", ["'a -> 'b"]
+
+                """
+                let foo x = 
+                    let bar y = x + y
+                    bar(
+                """, "bar(", ["int"]
+
+                """
+                type T() = 
+                    let foo x = x + 1
+                    member this.Run() = 
+                        foo(
+                """, "foo(", ["int"]
+
+                """
+                let f (Some x) = x + 1
+                f(
+                """, "f(", ["int option"]
+            ]
+
+        for (code, marker, expectedParams) in useCases do
+            let (_, _, file) = this.CreateSingleFileProject(code)
+            MoveCursorToEndOfMarker(file, marker)
+            let methodGroup = GetParameterInfoAtCursor file
+            
+            Assert.AreEqual(1, methodGroup.GetCount(), "Only one function expected")            
+
+            let expectedParamsCount = List.length expectedParams
+            Assert.AreEqual(expectedParamsCount, methodGroup.GetParameterCount(0), sprintf "%d parameters expected" expectedParamsCount)
+            
+            let actualParams = [ for i = 0 to (expectedParamsCount - 1) do yield methodGroup.GetParameterInfo(0, i) ]               
+            let ok = 
+                actualParams
+                |> List.map (fun (_, d, _) -> d)
+                |> List.forall2 (=) expectedParams
+            if not ok then
+                printfn "==Parameters dont't match=="
+                printfn "Expected parameters %A" expectedParams
+                printfn "Actual parameters %A" actualParams
+                Assert.Fail()
+                  
+    (* Tests for multi-parameterinfos ------------------------------------------------------------------ *)
+
+    [<Test>]
+    member public this.``ParameterInfo.ArgumentsWithParamsArrayAttribute``() =
+        let content = """let _ = System.String.Format("",(*MARK*))"""
+        let methodTip = this.GetMethodListForAMethodTip(content, "(*MARK*)")
+        let overloadWithTwoParamsOpt = 
+            Seq.init (methodTip.GetCount()) (fun i -> 
+                let count = methodTip.GetParameterCount(i)
+                let paramInfos = 
+                    [
+                        for c = 0 to (count - 1) do
+                            let name = ref ""
+                            let display = ref ""
+                            let description = ref ""
+                            methodTip.GetParameterInfo(i, c, name, display, description)
+                            yield !name, !display,!description
+                    ]
+                count, paramInfos
+                )
+            |> Seq.tryFind(fun (i, _) -> i = 2)
+        match overloadWithTwoParamsOpt with
+        | Some(_, [_;(_name, display, _description)]) -> Assert.IsTrue(display.Contains("params args"))
+        | x -> Assert.Fail(sprintf "Expected overload not found, current result %A" x)
+
+    (* DotNet functions for multi-parameterinfo tests -------------------------------------------------- *)
+    [<Test>]
+    member public this.``Multi.DotNet.StaticMethod``() =
+        let fileContents = """System.Console.WriteLine("Today is {0:dd MMM yyyy}",(*Mark*)System.DateTime.Today)"""
+        this.VerifyParameterInfoContainedAtStartOfMarker(fileContents,"(*Mark*)",["string";"obj"])
+
+    [<Test>]
+    member public this.``Multi.DotNet.StaticMethod.WithinClassMember``() =
+        let fileContents = """
+            type Widget(z) = 
+                member x.a = (1 <> System.Int32.Parse("",(*Mark*)
+
+            let widget = Widget(1)
+            45"""
+        this.VerifyParameterInfoContainedAtStartOfMarker(fileContents,"(*Mark*)",["string";"System.Globalization.NumberStyles"])
+
+    [<Test>]
+    member public this.``Multi.DotNet.StaticMethod.WithinLambda``() =
+        let fileContents = """let z = fun x -> x + System.Int16.Parse("",(*Mark*)"""
+        this.VerifyParameterInfoContainedAtStartOfMarker(fileContents,"(*Mark*)",["string";"System.Globalization.NumberStyles"])
+
+    [<Test>]
+    member public this.``Multi.DotNet.StaticMethod.WithinLambda2``() = 
+        let fileContents = "let _ = fun file -> new System.IO.FileInfo((*Mark*)"
+        this.VerifyParameterInfoAtStartOfMarker(fileContents,"(*Mark*)",[["string"]])
+
+    [<Test>]
+    member public this.``Multi.DotNet.InstanceMethod``() = 
+        let fileContents = """
+            let s = "Hello"
+            s.Substring(0,(*Mark*)"""
+        this.VerifyParameterInfoContainedAtStartOfMarker(fileContents,"(*Mark*)",["int";"int"])
+
+    (* Common functions for multi-parameterinfo tests -------------------------------------------------- *)
+    [<Test>]
+    member public this.``Multi.DotNet.Constructor``() = 
+        let fileContents = "let _ = new System.DateTime(2010,12,(*Mark*)"
+        this.VerifyParameterInfoContainedAtStartOfMarker(fileContents,"(*Mark*)",["int";"int";"int"])
+
+    [<Test>]
+    member public this.``Multi.Constructor.WithinObjectExpression``() = 
+        let fileContents = "let _ = { new System.Object((*Mark*)) with member __.GetHashCode() = 2}"
+        this.VerifyParameterInfoContainedAtStartOfMarker(fileContents,"(*Mark*)",[])
+
+    [<Test>]
+    member public this.``Multi.Function.InTheClassMember``() = 
+        let fileContents = """
+            type Foo() = 
+                let foo1(a : int, b:int) = ()
+
+                member this.A() = 
+                    foo1(1,(*Mark*)
+                member this.A(a : string, b:int) = ()"""
+        this.VerifyParameterInfoAtStartOfMarker(fileContents,"(*Mark*)",[["int";"int"]])
+
+    [<Test>]
+    member public this.``Multi.ParamAsTupleType``() = 
+        let fileContents = """
+            let tuple((a : int, b : int), c : int) = a * b + c
+            let result = tuple((1, 2)(*Mark*), 3)"""
+        this.VerifyParameterInfoAtStartOfMarker(fileContents,"(*Mark*)",[["int * int";"int"]])
+
+    [<Test>]
+    member public this.``Multi.ParamAsCurryType``() = 
+        let fileContents = """
+            let multi (x : float) (y : float) = 0
+            let sum(a, b) = a + b
+            let rtnValue = sum(multi (1.0(*Mark*)) 3.0, 5)"""
+        this.VerifyParameterInfoAtStartOfMarker(fileContents,"(*Mark*)",[["float"]])
+
+    [<Test>]
+    member public this.``Multi.MethodInMatchCause``() = 
+        let fileContents = """
+            let rec f l = 
+                    match l with
+                    | [] -> System.String.Format("{0:X2}",(*Mark*)
+                    | x :: xs -> f xs"""
+        this.VerifyParameterInfoContainedAtStartOfMarker(fileContents,"(*Mark*)",["string";"obj"])
+
+    [<Test>]
+    [<Ignore("93945 - No param info shown on the Indexer Property")>]
+    member public this.``Regression.Multi.IndexerProperty.Bug93945``() = 
+        let fileContents = """
+            type Year2(year : int) =
+              member this.Item (month : int, day : int) =
+                let monthIdx =
+                    match month with
+                    | _ when month > 12 -> failwithf "Invalid month [%d]" month
+                    | _ when month < 1 -> failwithf "Invalid month [%d]" month
+                    | _ -> month
+                let dateStr = sprintf "1-1-%d" year
+                DateTime.Parse(dateStr).AddMonths(monthIdx - 1).AddDays(float (day - 1))
+
+            let O'seven = new Year2(2007)
+            let randomDay = O'seven.[12,(*Mark*)"""
+        this.VerifyParameterInfoAtStartOfMarker(fileContents,"(*Mark*)",[["int";"int"]])
+
+    [<Test>]
+    [<Ignore("93188 - No param info shown in the Attribute memthod")>]
+    member public this.``Regression.Multi.ExplicitAnnotate.Bug93188``() = 
+        let fileContents = """
+            type LiveAnimalAttribute(a : int, b: string) =
+                inherit System.Attribute()
+
+            [<LiveAnimal(1,(*Mark*)"Bat")>]
+            type Wombat() = class end"""
+        this.VerifyParameterInfoAtStartOfMarker(fileContents,"(*Mark*)",[["int";"string"]])
+
+    [<Test>]
+    member public this.``Multi.Function.WithRecordType``() = 
+        let fileContents = """
+            type Vector =
+                { X : float; Y : float; Z : float }
+            let foo(x : int,v : Vector) = ()
+            foo(12, { X = 10.0; Y = (*Mark*)20.0; Z = 30.0 })"""
+        this.VerifyParameterInfoAtStartOfMarker(fileContents,"(*Mark*)",[["int";"Vector"]])
+
+    [<Test>]
+    member public this.``Multi.Function.AsParameter``() = 
+        let fileContents = """
+            let isLessThanZero x = (x < 0)
+            let containsNegativeNumbers intList =
+                let filteredList = List.filter isLessThanZero intList
+                if List.length filteredList > 0
+                then Some(filteredList)
+                else None
+            let _ = Option.get(containsNegativeNumbers [6; 20; (*Mark*)8; 45; 5])"""
+        this.VerifyParameterInfoAtStartOfMarker(fileContents,"(*Mark*)",[["int list"]])
+
+    [<Test>]
+    member public this.``Multi.Function.WithOptionType``() = 
+        let fileContents = """
+            let foo( a : int option, b : string ref) = 0
+            let _ = foo(Some(12),(*Mark*)"""
+        this.VerifyParameterInfoAtStartOfMarker(fileContents,"(*Mark*)",[["int option";"string ref"]])
+
+    [<Test>]
+    member public this.``Multi.Function.WithOptionType2``() = 
+        let fileContents = """
+            let multi (x : float) (y : float) = x * y
+            let sum(a : int, b) = a + b
+            let options(a1 : int option, b1 : float option) = a1.ToString() + b1.ToString()
+            let rtnOption = options(Some(sum(1, 3)), (*Mark*)Some(multi 3.1 5.0)) """
+        this.VerifyParameterInfoAtStartOfMarker(fileContents,"(*Mark*)",[["int option";"float option"]])
+
+    [<Test>]
+    member public this.``Multi.Function.WithRefType``() = 
+        let fileContents = """
+            let foo( a : int ref, b : string ref) = 0
+            let _ = foo(ref 12,(*Mark*)"""
+        this.VerifyParameterInfoAtStartOfMarker(fileContents,"(*Mark*)",[["int ref";"string ref"]])
+
+    (* Overload list/Adjust method's param for multi-parameterinfo tests ------------------------------ *)
+
+    [<Test>]
+    member public this.``Multi.OverloadMethod.OrderedParamters``() = 
+        let fileContents = "new System.DateTime(2000,12,(*Mark*)"
+        this.VerifyParameterInfoOverloadMethodIndex(fileContents,"(*Mark*)",3(*The fourth method*),["int";"int";"int"])
+
+    [<Test>]
+    member public this.``Multi.Overload.WithSameParameterCount``() = 
+        let fileContents = """
+            type Foo() = 
+              member this.A1(x1 : int, x2 : int, ?y : string, ?Z: bool) = ()
+              member this.A1(x1 : int, X2 : string, ?y : int, ?Z: bool) = ()
+            let foo = new Foo()
+            foo.A1(1,1,(*Mark*)"""
+        this.VerifyParameterInfoAtStartOfMarker(fileContents,"(*Mark*)",[["int";"int";"string";"bool"];["int";"string";"int";"bool"]])
+        
+    [<Test>]
+    member public this.``ExtensionMethod.Overloads``() = 
+        let fileContents = """
+            module MyCode =
+                type A() = 
+                    member this.Method(a:string) = ""
+            module MyExtension = 
+                type MyCode.A with
+                    member this.Method(a:int) = ""
+            
+            open MyCode
+            open MyExtension
+            let foo = A()
+            foo.Method((*Mark*)"""
+        this.VerifyParameterInfoAtStartOfMarker(fileContents,"(*Mark*)",[["string"];["int"]])
+ 
+    [<Test>]
+    [<Ignore("Parameterinfo not retrieved properly for indexed properties by test infra")>]
+    member public this.``ExtensionProperty.Overloads``() = 
+        let fileContents = """
+            module MyCode =
+                type A() = 
+                    member this.Prop with get(a:string) = ""
+            module MyExtension = 
+                type MyCode.A with
+                    member this.Prop with get(a:int) = ""
+            
+            open MyCode
+            open MyExtension
+            let foo = A()
+            foo.Prop((*Mark*)"""
+        this.VerifyParameterInfoAtStartOfMarker(fileContents,"(*Mark*)",[["string"];["int"]])
+        
+    (* Generic functions for multi-parameterinfo tests ------------------------------------------------ *)
+
+    [<Test>]
+    member public this.``Multi.Generic.ExchangeInt``() = 
+        let fileContents = "System.Threading.Interlocked.Exchange<int>(123,(*Mark*)"
+        this.VerifyParameterInfoContainedAtStartOfMarker(fileContents,"(*Mark*)",["byref<int>";"int"])
+
+    [<Test>]
+    member public this.``Multi.Generic.Exchange.``() = 
+        let fileContents = "System.Threading.Interlocked.Exchange(12.0,(*Mark*)"
+        this.VerifyParameterInfoContainedAtStartOfMarker(fileContents,"(*Mark*)",["byref<float>";"float"])
+
+    [<Test>]
+    member public this.``Multi.Generic.ExchangeUnder``() = 
+        let fileContents = "System.Threading.Interlocked.Exchange<_> (obj,(*Mark*)"
+        this.VerifyParameterInfoContainedAtStartOfMarker(fileContents,"(*Mark*)",["byref<obj>";"obj"])
+
+    [<Test>]
+    member public this.``Multi.Generic.Dictionary``() = 
+        let fileContents = "System.Collections.Generic.Dictionary<_, option<int>>(12,(*Mark*)"
+        this.VerifyParameterInfoContainedAtStartOfMarker(fileContents,"(*Mark*)",["int";"System.Collections.Generic.IEqualityComparer<obj>"])
+
+    [<Test>]
+    [<Ignore("95862 - [Unittests] parseInfo(TypeCheckResult.TypeCheckInfo).GetMethods can not get MethodOverloads")>]
+    member public this.``Multi.Generic.HashSet``() = 
+        let fileContents = "System.Collections.Generic.HashSet<int>({ 1 ..12 },(*Mark*)"
+        this.VerifyParameterInfoContainedAtStartOfMarker(fileContents,"(*Mark*)",["Seq<'a>";"System.Collections.Generic.IEqualityComparer<'a>"])
+    
+    [<Test>]
+    [<Ignore("95862 - [Unittests] parseInfo(TypeCheckResult.TypeCheckInfo).GetMethods can not get MethodOverloads")>]
+    member public this.``Multi.Generic.SortedList``() = 
+        let fileContents = "System.Collections.Generic.SortedList<_,option<int>> (12,(*Mark*)"
+        this.VerifyParameterInfoContainedAtStartOfMarker(fileContents,"(*Mark*)",["int";"System.Collections.Generic.IComparer<'TKey>"])
+    
+    (* No Param Info Shown for multi-parameterinfo tests ---------------------------------------------- *)
+
+    [<Test>]
+    member public this.``ParameterInfo.Multi.NoParamterInfo.InComments``() = 
+        let fileContents = "//let _ = System.Object((*Mark*))"
+        this.VerifyNoParameterInfoAtStartOfMarker(fileContents,"(*Mark*)")
+    
+    [<Test>]
+    member public this.``Multi.NoParameterInfo.InComments2``() = 
+        let fileContents = """(*System.Console.WriteLine((*Mark*)"Test on Fsharp style comments.")*)"""
+        this.VerifyNoParameterInfoAtStartOfMarker(fileContents,"(*Mark*)")
+
+    [<Test>]
+    member public this.``Multi.NoParamterInfo.OnFunctionDeclaration``() = 
+        let fileContents = "let Foo(x : int, (*Mark*)b : string) = ()"
+        this.VerifyNoParameterInfoAtStartOfMarker(fileContents,"(*Mark*)")
+
+    [<Test>]
+    member public this.``Multi.NoParamterInfo.WithinString``() = 
+        let fileContents = """let s = "new System.DateTime(2000,12(*Mark*)" """
+        this.VerifyNoParameterInfoAtStartOfMarker(fileContents,"(*Mark*)")
+
+    [<Test>]
+    member public this.``Multi.NoParamterInfo.OnProperty``() = 
+        let fileContents = """
+            let s = "Hello"
+            let _ = s.Length(*Mark*)"""
+        this.VerifyNoParameterInfoAtStartOfMarker(fileContents,"(*Mark*)")
+
+    [<Test>]
+    member public this.``Multi.NoParamterInfo.OnValues``() = 
+        let fileContents = """
+            type Foo = class
+                val private size : int
+                val private path : string
+                new (s : int, p : string) = {size = s; path(*Mark*) = p}
+            end"""
+        this.VerifyNoParameterInfoAtStartOfMarker(fileContents,"(*Mark*)")
+
+    (* Project ref method for multi-parameterinfo tests ----------------------------------------------- *)
+
+    [<Test>]
+    member public this.``Multi.ReferenceToProjectLibrary``() = 
+        use _guard = this.UsingNewVS()
+        let solution = this.CreateSolution()
+        let project1 = CreateProject(solution, "FSharpLib")
+        let project2 = CreateProject(solution, "FSharpPro")
+        AddProjectReference(project2,project1)
+        let _ = AddFileFromText(project1, "file1.fs", ["namespace Test";"type public Foo() = class";"  static member Sum(x:int,y:int) = x+y";"end"])
+        let result1 = Build(project1)
+        AddFileFromText(project2, "file2.fs", ["open Test";"Foo.Sum(12,(*Mark*)"]) |> ignore
+        let result2 = Build(project2)
+        let file = OpenFile(project2, "file2.fs")
+        MoveCursorToStartOfMarker(file, "(*Mark*)")
+
+        let methodstr = GetParameterInfoAtCursor(file)
+        AssertMethodGroupContain(methodstr,["int";"int"])
+
+    (* Regression tests/negative tests for multi-parameterinfos --------------------------------------- *) 
+    // To be added when the bugs are fixed...
+    [<Test>]
+    //[<Ignore("90832 - [ParameterInfo] No Parameter Info shown on string parameter with operator")>]
+    member public this.``Regrssion.ParameterWithOperators.Bug90832``() = 
+        let fileContents = """System.Console.WriteLine("This(*Mark*) is a" + " bug.")"""
+        this.VerifyParameterInfoContainedAtStartOfMarker(fileContents,"(*Mark*)",["string"])
+
+    [<Test>]
+    member public this.``Regression.OptionalArguuments.Bug4042``() = 
+        let fileContents = """
+            module ParameterInfo
+            type TT(x : int, ?y : int) = 
+                let z = y
+                do printfn "%A" z
+                member this.Foo(?z : int) = z
+    
+            type TT2(x : int, y : int option) = 
+                let z  = y
+                do printfn "%A" z
+            let tt = TT((*Mark*)"""
+        this.VerifyParameterInfoAtStartOfMarker(fileContents,"(*Mark*)",[["int";"int"]])
+
+    [<Test>]
+    //[<Ignore("90798 - [ParameterInfo] No param info when typing ( for the first time")>]
+    member public this.``Regression.ParameterFirstTypeOpenParen.Bug90798``() = 
+        let fileContents = """
+            let a = async {
+                    Async.AsBeginEnd((*Mark*)
+                }
+            let p = 10"""
+        this.VerifyParameterInfoAtStartOfMarker(fileContents,"(*Mark*)",[["'Arg -> Async<'T>"]])
+
+    [<Test>]   
+    // regression test for bug 3878: no parameter info triggered by "("
+    member public this.``Regression.NoParameterInfoTriggeredByOpenBrace.Bug3878``() = 
+        let fileContents = """
+            module ParameterInfo
+            let x = 1 + 2
+
+            let _ = System.Console.WriteLine ((*Mark*))
+
+            let y = 1"""
+        this.VerifyParameterInfoContainedAtStartOfMarker(fileContents,"(*Mark*)",[""])
+
+    [<Test>]   
+    // regression test for bug 4495 : Should alway sort method lists in order of argument count
+    member public this.``Regression.MehtodSortedByArgumentCount.Bug4495.Case1``() = 
+        let fileContents = """
+            module ParameterInfo
+            
+            let a1 = System.Reflection.Assembly.Load("mscorlib")
+            let m = a1.GetType("System.Decimal").GetConstructor((*Mark*)null)"""
+        this.VerifyParameterInfoOverloadMethodIndex(fileContents,"(*Mark*)",0,["System.Type []"])
+
+    [<Test>]   
+    member public this.``Regression.MehtodSortedByArgumentCount.Bug4495.Case2``() = 
+        let fileContents = """
+            module ParameterInfo
+            
+            let a1 = System.Reflection.Assembly.Load("mscorlib")
+            let m = a1.GetType("System.Decimal").GetConstructor((*Mark*)null)"""
+        this.VerifyParameterInfoOverloadMethodIndex(fileContents,"(*Mark*)",1,["System.Reflection.BindingFlags";
+                                                                                "System.Reflection.Binder";
+                                                                                "System.Type []";
+                                                                                "System.Reflection.ParameterModifier []"])
+
+    [<Test>]   
+    [<Ignore("Bug 95862")>]
+    member public this.``BasicBehavior.WithReference``() = 
+        let fileContents = """
+            open System.ServiceModel
+            let serviceHost = new ServiceHost((*Mark*))"""
+        let (solution, project, file) = this.CreateSingleFileProject(fileContents, references = ["System.ServiceModel"])
+ 
+        MoveCursorToStartOfMarker(file, "(*Mark*)") 
+        TakeCoffeeBreak(this.VS)      
+        let methodstr = GetParameterInfoAtCursor(file)
+        printfn "%A" methodstr
+        let expected = ["System.Type";"System.Uri []"]
+        AssertMethodGroupContain(methodstr,expected)
+
+    [<Test>]   
+    member public this.``BasicBehavior.CommonFunction``() = 
+        let fileContents = """
+            let f(x) = 1
+            f((*Mark*))"""
+        this.VerifyParameterInfoAtStartOfMarker(fileContents,"(*Mark*)",[["'a"]])
+
+    [<Test>]   
+    member public this.``BasicBehavior.DotNet.Static``() = 
+        let fileContents = """System.String.Format((*Mark*)"""
+        this.VerifyParameterInfoContainedAtStartOfMarker(fileContents,"(*Mark*)",["string";"obj []"])
+
+(*------------------------------------------IDE Query automation start -------------------------------------------------*)
+    [<Test>]   
+    [<Category("Query")>]
+    // ParamInfo works normally for calls as query operator arguments
+    // wroks fine In nested queries
+    member public this.``Query.InNestedQuery``() = 
+        let fileContents = """
+        let tuples = [ (1, 8, 9); (56, 45, 3)] 
+        let numbers = [ 1;2; 8; 9; 15; 23; 3; 42; 4;0; 55;]
+        let tp = (2,3,6)
+        let foo = 
+            query {
+                for n in numbers do
+                yield (n, query {for x in tuples do 
+                                 let r = x.Equals((*Marker1*)tp)
+                                 let _ = System.String.Format("",(*Marker2*)x)
+                                 select r })
+                }"""
+        this.VerifyParameterInfoContainedAtStartOfMarker(fileContents,"(*Marker1*)",["obj"],queryAssemblyRefs)
+        this.VerifyParameterInfoContainedAtStartOfMarker(fileContents,"(*Marker2*)",["string";"obj []"],queryAssemblyRefs)
+
+    [<Test>]   
+    [<Category("Query")>]
+    // ParamInfo works normally for calls as query operator arguments
+    // ParamInfo Still works when an error exists
+    member public this.``Query.WithErrors``() = 
+        let fileContents = """
+        let tuples = [ (1, 8, 9); (56, 45, 3)] 
+        let tp = (2,3,6)
+        let foo = 
+            query {
+                for t in tuples do
+                orderBy (t.Equals((*Marker*)tp))
+                }"""
+        this.VerifyParameterInfoContainedAtStartOfMarker(fileContents,"(*Marker*)",["obj"],queryAssemblyRefs)
+
+    [<Test>]   
+    [<Category("Query")>]
+    // ParamInfo works normally for calls as query operator arguments
+    member public this.``Query.OperatorWithParentheses``() = 
+        let fileContents = """
+        type Product() =
+            let mutable id = 0
+            let mutable name = ""
+
+            member x.ProductID with get() = id and set(v) = id <- v
+            member x.ProductName with get() = name and set(v) = name <- v
+
+        let getProductList() =
+            [
+            Product(ProductID = 1, ProductName = "Chai");
+            Product(ProductID = 2, ProductName = "Chang"); ]
+        let products = getProductList()
+        let categories = ["Beverages"; "Condiments"; "Vegetables";]
+        // Group Join
+        let q2 =
+            query {
+                for c in categories do
+                groupJoin((*Marker1*)for p in products(*Marker2*) -> c = p.ProductName) into ps
+                select (c, ps)
+            } |> Seq.toArray"""
+        this.VerifyParameterInfoContainedAtStartOfMarker(fileContents,"(*Marker1*)",[],queryAssemblyRefs)
+        this.VerifyParameterInfoContainedAtStartOfMarker(fileContents,"(*Marker2*)",[],queryAssemblyRefs)
+
+    [<Test>]   
+    [<Category("Query")>]
+    // ParamInfo works normally for calls as query operator arguments
+    // ParamInfo Still works when there is an optional argument
+    member public this.``Query.OptionalArgumentsInQuery``() = 
+        let fileContents = """
+        type TT(x : int, ?y : int) = 
+            let z = y
+            do printfn "%A" z
+            member this.Foo(?z : int) = z
+    
+        type TT2(x : int, y : int option) = 
+            let z  = y
+            do printfn "%A" z
+        let numbers = [ 1;2; 8; 9; 15; 23; 3; 42; 4;0; 55;]
+
+        let test3 =
+            query {
+                for n in numbers do
+                let tt = TT((*Marker*)
+                minBy n
+            }"""
+        this.VerifyParameterInfoContainedAtStartOfMarker(fileContents,"(*Marker*)",["int";"int"],queryAssemblyRefs)
+
+    [<Test>]   
+    [<Category("Query")>]
+    // ParamInfo works normally for calls as query operator arguments
+    // ParamInfo Still works when there are overload methods with the same param count
+    member public this.``Query.OverloadMethod.InQuery``() = 
+        let fileContents = """
+        let numbers = [ 1;2; 8; 9; 15; 23; 3; 42; 4;0; 55;]
+
+        type Foo() = 
+            member this.A1(x1 : int, x2 : int, ?y : string, ?Z: bool) = ()
+            member this.A1(x1 : int, X2 : string, ?y : int, ?Z: bool) = ()
+
+        let test3 =
+            query {
+                for n in numbers do
+                let foo = new Foo()
+                foo.A1(1,1,(*Marker*)
+                minBy n
+            }"""
+        this.VerifyParameterInfoContainedAtStartOfMarker(fileContents,"(*Marker*)",["int";"int";"string";"bool"],queryAssemblyRefs)
+
+
+// Allow the ParameterInfoTests run under different context
+namespace UnitTests.Tests.LanguageService.ParameterInfo
+open UnitTests.Tests.LanguageService
+open UnitTests.TestLib.LanguageService
+open UnitTests.TestLib.ProjectSystem
+open NUnit.Framework
+open Salsa.Salsa
+
+// context msbuild
+[<TestFixture>] 
+[<Category("LanguageService.MSBuild")>]
+type ``MSBuild`` = 
+   inherit ParameterInfoTests
+   new() = { inherit ParameterInfoTests(VsOpts = fst (Models.MSBuild())); }
+
+// Context project system
+[<TestFixture>] 
+[<Category("LanguageService.ProjectSystem")>]
+type ``ProjectSystem`` = 
+    inherit ParameterInfoTests
+    new() = { inherit ParameterInfoTests(VsOpts = LanguageServiceExtension.ProjectSystem); } 
diff --git a/vsintegration/src/unittests/Tests.LanguageService.QuickInfo.fs b/vsintegration/src/unittests/Tests.LanguageService.QuickInfo.fs
new file mode 100644
index 0000000..8cc499b
--- /dev/null
+++ b/vsintegration/src/unittests/Tests.LanguageService.QuickInfo.fs
@@ -0,0 +1,3654 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+namespace UnitTests.Tests.LanguageService
+
+open System
+open NUnit.Framework
+open Salsa.Salsa
+open Salsa.VsOpsUtils
+open UnitTests.TestLib.Salsa
+open UnitTests.TestLib.Utils
+open UnitTests.TestLib.LanguageService
+
+[<AutoOpen>]
+module QuickInfoStandardSettings = 
+    let standard40AssemblyRefs  = [ "System"; "System.Core"; "System.Numerics" ]
+    let queryAssemblyRefs = [ "System.Xml.Linq"; "System.Core" ]
+type QuickInfoTests() = 
+    inherit LanguageServiceBaseTests()
+
+    // Work around an innocuous 'feature' with how QuickInfo is displayed, lines which 
+    // should have a "\r\n" just have a "\r"
+    let trimnewlines (str : string) = 
+        str.Replace("\r", "").Replace("\n", "")
+    
+    let stopWatch = new System.Diagnostics.Stopwatch()
+    let ResetStopWatch() = stopWatch.Reset(); stopWatch.Start()
+    let time1 op a message = 
+        ResetStopWatch()
+        let result = op a
+        //printf "%s %d ms\n" message stopWatch.ElapsedMilliseconds
+        result
+
+    let ShowErrors(project:OpenProject) =     
+        for error in (GetErrors(project)) do
+            printf "%s\n" (error.ToString()) 
+
+    let checkTooltip expected ((tooltip, span : TextSpan), (row, col)) = 
+        AssertContains(tooltip, expected)
+        // cursor should be inside the span
+        Assert.IsTrue(row = (span.iStartLine + 1) && row = (span.iEndLine + 1), "Cursor should be one the same line with the tooltip span")
+        Assert.IsTrue(col >= span.iStartIndex && col <= span.iEndIndex, "Cursor should be located inside the span")
+
+
+//    (* Tests for QuickInfos ---------------------------------------------------------------- *)
+    member public this.InfoInDeclarationTestQuickInfoImplWithTrim (code : string) marker expected =
+        let (_, _, file) = this.CreateSingleFileProject(code)
+        let gpatcc = GlobalParseAndTypeCheckCounter.StartNew(this.VS)
+        MoveCursorToStartOfMarker(file, marker)
+        let tooltip = time1 GetQuickInfoAtCursor file "Time of first tooltip"
+        AssertContains(trimnewlines tooltip, trimnewlines expected) 
+        gpatcc.AssertExactly(0,0)
+
+    member public this.CheckTooltip(code : string,marker,atStart, f, ?addtlRefAssy : list<string>) =
+        let (_, _, file) = this.CreateSingleFileProject(code, ?references = addtlRefAssy)
+
+        let gpatcc = GlobalParseAndTypeCheckCounter.StartNew(this.VS)
+        if atStart then
+            MoveCursorToStartOfMarker(file, marker)
+        else
+            MoveCursorToEndOfMarker(file, marker)
+        let pos = GetCursorLocation file
+        let tooltip = GetQuickInfoAndSpanAtCursor file
+        f (tooltip, pos)
+        gpatcc.AssertExactly(0,0)
+                         
+    member public this.InfoInDeclarationTestQuickInfoImpl(code,marker,expected,atStart, ?addtlRefAssy : list<string>) =
+        let check ((tooltip, _), _) = AssertContains(tooltip, expected)
+        this.CheckTooltip(code, marker, atStart, check, ?addtlRefAssy=addtlRefAssy )
+
+    member public this.AssertQuickInfoContainsAtEndOfMarker(code,marker,expected, ?addtlRefAssy : list<string>) =
+        this.InfoInDeclarationTestQuickInfoImpl(code,marker,expected,false,?addtlRefAssy=addtlRefAssy)
+
+    member public this.AssertQuickInfoContainsAtStartOfMarker(code, marker, expected, ?addtlRefAssy : list<string>) =
+        this.InfoInDeclarationTestQuickInfoImpl(code,marker,expected,true,?addtlRefAssy=addtlRefAssy)
+        
+    member public this.VerifyQuickInfoDoesNotContainAnyAtEndOfMarker (code : string) marker notexpected =
+        let (_, _, file) = this.CreateSingleFileProject(code)
+        
+        let gpatcc = GlobalParseAndTypeCheckCounter.StartNew(this.VS)
+        MoveCursorToEndOfMarker(file, marker)
+        let tooltip = time1 GetQuickInfoAtCursor file "Time of first tooltip"
+        AssertNotContains(tooltip, notexpected)         
+        gpatcc.AssertExactly(0,0)
+
+    member public this.VerifyQuickInfoDoesNotContainAnyAtStartOfMarker (code : string) marker notexpected =
+        let (_, _, file) = this.CreateSingleFileProject(code)
+        
+        let gpatcc = GlobalParseAndTypeCheckCounter.StartNew(this.VS)
+        MoveCursorToStartOfMarker(file, marker)
+        let tooltip = time1 GetQuickInfoAtCursor file "Time of first tooltip"
+        AssertNotContains(tooltip, notexpected)         
+        gpatcc.AssertExactly(0,0)
+
+    member public this.AssertIdentifierInToolTipExactlyOnce (code : string) marker ident =
+    /// Asserts that an identifier occurs exactly once in a tooltip
+        let AssertIdentifierInToolTipExactlyOnce(ident, (tooltip:string)) =
+            let count = tooltip.Split([| '='; '.'; ' '; '\t'; '('; ':'; ')'; '\n' |]) |> Array.filter ((=) ident) |> Array.length
+            if (count <> 1) then
+                Assert.Fail(sprintf "Identifier '%s' doesn't occure once in the tooltip '%s'" ident tooltip)
+        
+        let (_, _, file) = this.CreateSingleFileProject(code)
+
+        let gpatcc = GlobalParseAndTypeCheckCounter.StartNew(this.VS)
+        MoveCursorToEndOfMarker(file, marker)
+        let tooltip = GetQuickInfoAtCursor file
+        AssertIdentifierInToolTipExactlyOnce(ident, tooltip)
+        gpatcc.AssertExactly(0,0)
+
+    member this.VerifyOrderOfNestedTypesInQuickInfo (source : string, marker : string, expectedExactOrder : string list, ?extraRefs : string list) = 
+        let (_, _, file) = this.CreateSingleFileProject(source, ?references = extraRefs)
+        
+        let gpatcc = GlobalParseAndTypeCheckCounter.StartNew(this.VS)
+        MoveCursorToStartOfMarker(file, "(*M*)")
+        let tooltip = time1 GetQuickInfoAtCursor file "Time of first tooltip"
+        AssertContainsInOrder(tooltip, expectedExactOrder)
+  
+    
+    [<Test>]
+    member public this.``EmptyTypeTooltipBody``() = 
+        let content = """
+        type X(*M*) = class end"""
+        this.VerifyQuickInfoDoesNotContainAnyAtStartOfMarker content "(*M*)" "="
+
+    [<Test>]
+    member public this.``NestedTypesOrder``() = 
+        this.VerifyOrderOfNestedTypesInQuickInfo(
+            source = "type t = System.Runtime.CompilerServices.RuntimeHelpers(*M*)",
+            marker = "(*M*)",
+            expectedExactOrder = ["CleanupCode"; "TryCode"]
+            )
+
+        this.VerifyOrderOfNestedTypesInQuickInfo(
+            source = "type t = System.Collections.Generic.Dictionary(*M*)",
+            marker = "(*M*)",
+            expectedExactOrder = ["Enumerator"; "KeyCollection"; "ValueCollection"]
+            )
+    
+    [<Test>]
+    member public this.``Operators.TopLevel``() =
+        let source = """
+            /// tooltip for operator
+            let (===) a b = a + b
+            let _ = "" === ""
+            """
+        this.CheckTooltip(
+            code = source,
+            marker = "== \"\"",
+            atStart = true,
+            f = (fun ((text, _), _) -> printfn "actual %s" text; Assert.IsTrue(text.Contains "tooltip for operator"))
+            )
+            
+    [<Test>]
+    member public this.``Operators.Member``() =
+        let source = """
+            type U = U
+                with
+                /// tooltip for operator
+                static member (+++) (U, U) = U
+            let _ = U +++ U
+            """
+        this.CheckTooltip(
+            code = source,
+            marker = "++ U",
+            atStart = true,
+            f = (fun ((text, _), _) -> printfn "actual %s" text; Assert.IsTrue(text.Contains "tooltip for operator"))
+            )
+    
+    [<Test>]
+    member public this.``QuickInfo.OverriddenMethods``() =
+        let source = """
+            type A() =
+                abstract member M : unit -> unit
+                /// 1234
+                default this.M() = ()
+
+            type AA() = 
+                inherit A()
+                /// 5678
+                override this.M() = ()
+            let x = new AA()
+            x.M()
+
+            let y = new A()
+            y.M()
+            """
+        for (marker, expected) in ["x.M", "5678"; "y.M", "1234"] do
+            this.CheckTooltip
+                (
+                    code = source,
+                    marker = marker,
+                    atStart = false,
+                    f = (fun ((text : string, _), _) -> printfn "expected %s, actual %s" expected text; Assert.IsTrue (text.Contains(expected)))
+                )
+
+    [<Test>]
+    member public this.``QuickInfoForQuotedIdentifiers``() =
+        let source = """
+            /// The fff function
+            let fff x = x
+            /// The gg gg function
+            let ``gg gg`` x = x
+            let r = fff 1 + ``gg gg`` 2  // no tip hovering over"""
+        let identifier = "``gg gg``"
+        for i = 1 to (identifier.Length - 1) do
+            let marker = "+ " + (identifier.Substring(0, i))
+            this.CheckTooltip (source, marker, false, checkTooltip "gg gg")
+    [<Test>]
+    member public this.``QuickInfoSingleCharQuotedIdentifier``() = 
+        let source = """
+        let ``x`` = 10
+        ``x``|> printfn "%A"
+        """
+        this.CheckTooltip(source, "x``|>", true, checkTooltip "x")
+
+    [<Test>]
+    [<Category("TypeProvider")>]
+    member public this.``TypeProviders.NestedTypesOrder``() = 
+        let code = "type t = N1.TypeWithNestedTypes(*M*)"
+        let tpReference = System.IO.Path.Combine(System.Environment.CurrentDirectory, @"UnitTestsResources\MockTypeProviders\DummyProviderForLanguageServiceTesting.dll")
+        this.VerifyOrderOfNestedTypesInQuickInfo(
+            source = code,
+            marker = "(*M*)",
+            expectedExactOrder = ["A"; "X"; "Z"],
+            extraRefs = [tpReference]
+            ) 
+
+    [<Test>]
+    member public this.``GetterSetterInsideInterfaceImpl.ThisOnceAsserted``() =
+        let fileContent ="""
+            type IFoo =
+                abstract member X : int with get,set
+
+            type Bar =
+                interface IFoo with
+                    member this.X
+                        with get() = 42  // hello 
+                        and set(v) = id() """
+        this.AssertQuickInfoContainsAtStartOfMarker(fileContent, "id", "Operators.id")
+
+    //regression test for bug 3184 -- intellisense should normalize to ¡°int[]¡± so that [] is not mistaken for list.
+    [<Test>]
+    member public this.IntArrayQuickInfo() = 
+      
+        let fileContents = """
+                            let x(*MIntArray1*) : int array = [| 1; 2; 3 |]
+                            let y(*MInt[]*) : int []    = [| 1; 2; 3 |]
+                            """
+        this.AssertQuickInfoContainsAtStartOfMarker(fileContents, "x(*MIntArray1*)", "int array")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContents, "y(*MInt[]*)", "int []")
+        
+    //Verify no quickinfo -- link name string have 
+    [<Test>]
+    member public this.LinkNameStringQuickInfo() = 
+      
+        let fileContents = """
+                            let y = 1
+                            let f x = "x"(*Marker1*)
+                            let g z = "y"(*Marker2*)
+                            """
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContents, "\"x\"(*Marker1*)", "")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContents, "\"y\"(*Marker2*)", "")
+
+    [<Test>]
+    [<Category("TypeProvider")>]
+    [<Category("TypeProvider.XmlDocAttribute")>]
+    //This is to test the correct TypeProvider Type message is shown or not in the TypeProviderXmlDocAttribute
+    member public this.``TypeProvider.XmlDocAttribute.Type.Comment``() = 
+        
+        let fileContents = """
+                                let a = typeof<N.T(*Marker*)> """
+
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContents, "T(*Marker*)", "This is a synthetic type created by me!",
+         addtlRefAssy = [System.IO.Path.Combine(System.Environment.CurrentDirectory, @"UnitTestsResources\MockTypeProviders\XmlDocAttributeWithAdequateComment.dll")])
+    
+    [<Test>]
+    [<Category("TypeProvider")>]
+    [<Category("TypeProvider.XmlDocAttribute")>]
+    //This is to test for long message in the TypeProviderXmlDocAttribute for TypeProvider Type
+    member public this.``TypeProvider.XmlDocAttribute.Type.WithLongComment``() = 
+        
+        let fileContents = """
+                                let a = typeof<N.T(*Marker*)> """
+
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContents, "T(*Marker*)",
+         "This is a synthetic type created by me!. Which is used to test the tool tip of the typeprovider type to check if it shows the right message or not.",
+         addtlRefAssy = [System.IO.Path.Combine(System.Environment.CurrentDirectory, @"UnitTestsResources\MockTypeProviders\XmlDocAttributeWithLongComment.dll")])
+    
+    [<Test>]
+    [<Category("TypeProvider")>]
+    [<Category("TypeProvider.XmlDocAttribute")>]
+    //This is to test when the message is null in the TypeProviderXmlDocAttribute for TypeProvider Type
+    member public this.``TypeProvider.XmlDocAttribute.Type.WithNullComment``() = 
+        
+        let fileContents = """
+                                let a = typeof<N.T(*Marker*)> """
+
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContents, "T(*Marker*)",
+         "type T =\n  new : unit -> T\n  event Event1 : EventHandler\n  static member M : unit -> int []\n  static member StaticProp : decimal\n\nFull name: N.T", 
+         addtlRefAssy = [System.IO.Path.Combine(System.Environment.CurrentDirectory, @"UnitTestsResources\MockTypeProviders\XmlDocAttributeWithNullComment.dll")])
+    
+    [<Test>]
+    [<Category("TypeProvider")>]    
+    [<Category("TypeProvider.XmlDocAttribute")>]
+    //This is to test when there is empty message from the TypeProviderXmlDocAttribute for TypeProvider Type
+    member public this.``TypeProvider.XmlDocAttribute.Type.WithEmptyComment``() =
+
+        let fileContents = """
+                                let a = typeof<N.T(*Marker*)> """
+        
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContents, "T(*Marker*)",
+         "type T =\n  new : unit -> T\n  event Event1 : EventHandler\n  static member M : unit -> int []\n  static member StaticProp : decimal\n\nFull name: N.T",
+         addtlRefAssy = [System.IO.Path.Combine(System.Environment.CurrentDirectory, @"UnitTestsResources\MockTypeProviders\XmlDocAttributeWithEmptyComment.dll")])
+         
+
+    [<Test>]
+    [<Category("TypeProvider")>]
+    [<Category("TypeProvider.XmlDocAttribute")>]
+    //This is to test the multi-language in the TypeProviderXmlDocAttribute for TypeProvider Type
+    member public this.``TypeProvider.XmlDocAttribute.Type.LocalizedComment``() = 
+        
+        let fileContents = """
+                                let a = typeof<N.T(*Marker*)> """
+
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContents, "T(*Marker*)",
+         "This is a synthetic type Localized!  ኤፍ ሻርፕ",
+         addtlRefAssy = [System.IO.Path.Combine(System.Environment.CurrentDirectory, @"UnitTestsResources\MockTypeProviders\XmlDocAttributeWithLocalizedComment.dll")])
+   
+    [<Test>]
+    [<Category("TypeProvider")>]
+    [<Category("TypeProvider.XmlDocAttribute")>]
+    //This is to test the correct TypeProvider Constructor message is shown or not in the TypeProviderXmlDocAttribute
+    member public this.``TypeProvider.XmlDocAttribute.Constructor.Comment``() = 
+        
+        let fileContents = """
+                                let foo = new N.T(*Marker*)() """
+
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContents, "T(*Marker*)", "This is a synthetic .ctor created by me for N.T",
+         addtlRefAssy = [System.IO.Path.Combine(System.Environment.CurrentDirectory, @"UnitTestsResources\MockTypeProviders\XmlDocAttributeWithAdequateComment.dll")])
+    
+    [<Test>]
+    [<Category("TypeProvider")>]
+    [<Category("TypeProvider.XmlDocAttribute")>]
+    //This is to test for long message in the TypeProviderXmlDocAttribute for TypeProvider Constructor
+    member public this.``TypeProvider.XmlDocAttribute.Constructor.WithLongComment``() = 
+        
+        let fileContents = """
+                                let foo = new N.T(*Marker*)() """
+
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContents, "T(*Marker*)",
+         "This is a synthetic .ctor created by me for N.T. Which is used to test the tool tip of the typeprovider Constructor to check if it shows the right message or not.",
+         addtlRefAssy = [System.IO.Path.Combine(System.Environment.CurrentDirectory, @"UnitTestsResources\MockTypeProviders\XmlDocAttributeWithLongComment.dll")])
+    
+    [<Test>]
+    [<Category("TypeProvider")>]
+    [<Category("TypeProvider.XmlDocAttribute")>]
+    //This is to test when the message is null in the TypeProviderXmlDocAttribute for TypeProvider Constructor
+    member public this.``TypeProvider.XmlDocAttribute.Constructor.WithNullComment``() = 
+        
+        let fileContents = """
+                                let foo = new N.T(*Marker*)() """
+
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContents, "T(*Marker*)",
+         "N.T() : N.T", 
+         addtlRefAssy = [System.IO.Path.Combine(System.Environment.CurrentDirectory, @"UnitTestsResources\MockTypeProviders\XmlDocAttributeWithNullComment.dll")])
+    
+    [<Test>]
+    [<Category("TypeProvider")>]    
+    [<Category("TypeProvider.XmlDocAttribute")>]
+    //This is to test when there is empty message from the TypeProviderXmlDocAttribute for TypeProvider Constructor
+    member public this.``TypeProvider.XmlDocAttribute.Constructor.WithEmptyComment``() =
+
+        let fileContents = """
+                                let foo = new N.T(*Marker*)() """
+        
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContents, "T(*Marker*)",
+         "N.T() : N.T",
+         addtlRefAssy = [System.IO.Path.Combine(System.Environment.CurrentDirectory, @"UnitTestsResources\MockTypeProviders\XmlDocAttributeWithEmptyComment.dll")])
+    
+    [<Test>]
+    [<Category("TypeProvider")>]
+    [<Category("TypeProvider.XmlDocAttribute")>]
+    //This is to test the multi-language in the TypeProviderXmlDocAttribute for TypeProvider Constructor
+    member public this.``TypeProvider.XmlDocAttribute.Constructor.LocalizedComment``() = 
+        
+        let fileContents = """
+                                let foo = new N.T(*Marker*)() """
+
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContents, "T(*Marker*)",
+         "This is a synthetic .ctor Localized!  ኤፍ ሻርፕ for N.T",
+         addtlRefAssy = [System.IO.Path.Combine(System.Environment.CurrentDirectory, @"UnitTestsResources\MockTypeProviders\XmlDocAttributeWithLocalizedComment.dll")])
+        
+
+    [<Test>]
+    [<Category("TypeProvider")>]
+    [<Category("TypeProvider.XmlDocAttribute")>]
+    //This is to test the correct TypeProvider event message is shown or not in the TypeProviderXmlDocAttribute
+    member public this.``TypeProvider.XmlDocAttribute.Event.Comment``() = 
+        
+        let fileContents = """ 
+                                let t = new N.T()
+                                t.Event1(*Marker*)"""
+
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContents, "Event1(*Marker*)",
+         "This is a synthetic *event* created by me for N.T",
+         addtlRefAssy = [System.IO.Path.Combine(System.Environment.CurrentDirectory, @"UnitTestsResources\MockTypeProviders\XmlDocAttributeWithAdequateComment.dll")])
+    
+    [<Test>]
+    [<Category("TypeProvider")>]
+    [<Category("TypeProvider.XmlDocAttribute")>]
+    //This is to test the multi-language in the TypeProviderXmlDocAttribute for TypeProvider Event
+    member public this.``TypeProvider.XmlDocAttribute.Event.LocalizedComment``() = 
+        
+        let fileContents = """ 
+                                let t = new N.T()
+                                t.Event1(*Marker*)"""
+
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContents, "Event1(*Marker*)", 
+         "This is a synthetic *event* Localized!  ኤፍ ሻርፕ for N.T",
+         addtlRefAssy = [System.IO.Path.Combine(System.Environment.CurrentDirectory, @"UnitTestsResources\MockTypeProviders\XmlDocAttributeWithLocalizedComment.dll")])
+   
+    [<Test>]
+    [<Category("QuickInfo.ParamsAttribute")>]
+    //This is to test the multi-language in the TypeProviderXmlDocAttribute for TypeProvider Event
+    member public this.``TypeProvider.ParamsAttributeTest``() = 
+        
+        let fileContents = """ 
+                                let t = "a".Split('c')"""
+
+        this.AssertQuickInfoContainsAtEndOfMarker (fileContents, "Spl", "params separator")
+
+    [<Test>]
+    [<Category("TypeProvider")>]
+    [<Category("TypeProvider.XmlDocAttribute")>]
+    //This is to test for long message in the TypeProviderXmlDocAttribute for TypeProvider Event
+    member public this.``TypeProvider.XmlDocAttribute.Event.WithLongComment``() = 
+        
+        let fileContents = """ 
+                                let t = new N.T()
+                                t.Event1(*Marker*)"""
+
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContents, "Event1(*Marker*)",
+         "This is a synthetic *event* created by me for N.T. Which is used to test the tool tip of the typeprovider Event to check if it shows the right message or not.!",
+         addtlRefAssy = [System.IO.Path.Combine(System.Environment.CurrentDirectory, @"UnitTestsResources\MockTypeProviders\XmlDocAttributeWithLongComment.dll")])
+    
+    [<Test>]
+    [<Category("TypeProvider")>]
+    [<Category("TypeProvider.XmlDocAttribute")>]
+    //This is to test when the message is null in the TypeProviderXmlDocAttribute for TypeProvider Event
+    member public this.``TypeProvider.XmlDocAttribute.Event.WithNullComment``() = 
+        
+        let fileContents = """ 
+                                let t = new N.T()
+                                t.Event1(*Marker*)"""
+
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContents, "Event1(*Marker*)",
+         "event N.T.Event1: IEvent<System.EventHandler,System.EventArgs>", 
+         addtlRefAssy = [System.IO.Path.Combine(System.Environment.CurrentDirectory, @"UnitTestsResources\MockTypeProviders\XmlDocAttributeWithNullComment.dll")])
+    
+    [<Test>]
+    [<Category("TypeProvider")>]    
+    [<Category("TypeProvider.XmlDocAttribute")>]
+    //This is to test when there is empty message from the TypeProviderXmlDocAttribute for TypeProvider Event
+    member public this.``TypeProvider.XmlDocAttribute.Event.WithEmptyComment``() =
+
+        let fileContents = """ 
+                                let t = new N.T()
+                                t.Event1(*Marker*)"""
+        
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContents, "Event1(*Marker*)",
+         "event N.T.Event1: IEvent<System.EventHandler,System.EventArgs>",
+         addtlRefAssy = [System.IO.Path.Combine(System.Environment.CurrentDirectory, @"UnitTestsResources\MockTypeProviders\XmlDocAttributeWithEmptyComment.dll")])
+    
+
+    [<Test>]
+    [<Category("TypeProvider")>]
+    [<Category("TypeProvider.XmlDocAttribute")>]
+    //This is to test the correct TypeProvider Method message is shown or not in the TypeProviderXmlDocAttribute
+    member public this.``TypeProvider.XmlDocAttribute.Method.Comment``() = 
+        
+        let fileContents = """ 
+                                let t = new N.T.M(*Marker*)()"""
+
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContents, "M(*Marker*)",
+         "This is a synthetic *method* created by me!!",
+         addtlRefAssy = [System.IO.Path.Combine(System.Environment.CurrentDirectory, @"UnitTestsResources\MockTypeProviders\XmlDocAttributeWithAdequateComment.dll")])
+    
+    [<Test>]
+    [<Category("TypeProvider")>]
+    [<Category("TypeProvider.XmlDocAttribute")>]
+    //This is to test the multi-language in the TypeProviderXmlDocAttribute for TypeProvider Method
+    member public this.``TypeProvider.XmlDocAttribute.Method.LocalizedComment``() = 
+        
+        let fileContents = """ 
+                                let t = new N.T.M(*Marker*)()"""
+
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContents, "M(*Marker*)", 
+         "This is a synthetic *method* Localized!  ኤፍ ሻርፕ",
+         addtlRefAssy = [System.IO.Path.Combine(System.Environment.CurrentDirectory, @"UnitTestsResources\MockTypeProviders\XmlDocAttributeWithLocalizedComment.dll")])
+   
+    [<Test>]
+    [<Category("TypeProvider")>]
+    [<Category("TypeProvider.XmlDocAttribute")>]
+    //This is to test for long message in the TypeProviderXmlDocAttribute for TypeProvider Method
+    member public this.``TypeProvider.XmlDocAttribute.Method.WithLongComment``() = 
+        
+        let fileContents = """ 
+                                let t = new N.T.M(*Marker*)()"""
+
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContents, "M(*Marker*)",
+         "This is a synthetic *method* created by me!!. Which is used to test the tool tip of the typeprovider Method to check if it shows the right message or not.!",
+         addtlRefAssy = [System.IO.Path.Combine(System.Environment.CurrentDirectory, @"UnitTestsResources\MockTypeProviders\XmlDocAttributeWithLongComment.dll")])
+    
+    [<Test>]
+    [<Category("TypeProvider")>]
+    [<Category("TypeProvider.XmlDocAttribute")>]
+    //This is to test when the message is null in the TypeProviderXmlDocAttribute for TypeProvider Method
+    member public this.``TypeProvider.XmlDocAttribute.Method.WithNullComment``() = 
+        
+        let fileContents = """ 
+                                let t = new N.T.M(*Marker*)()"""
+
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContents, "M(*Marker*)",
+         "N.T.M() : int []", 
+         addtlRefAssy = [System.IO.Path.Combine(System.Environment.CurrentDirectory, @"UnitTestsResources\MockTypeProviders\XmlDocAttributeWithNullComment.dll")])
+    
+    [<Test>]
+    [<Category("TypeProvider")>]    
+    [<Category("TypeProvider.XmlDocAttribute")>]
+    //This is to test when there is empty message from the TypeProviderXmlDocAttribute for TypeProvider Method
+    member public this.``TypeProvider.XmlDocAttribute.Method.WithEmptyComment``() =
+
+        let fileContents = """ 
+                                let t = new N.T.M(*Marker*)()"""
+        
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContents, "M(*Marker*)",
+         "N.T.M() : int []",
+         addtlRefAssy = [System.IO.Path.Combine(System.Environment.CurrentDirectory, @"UnitTestsResources\MockTypeProviders\XmlDocAttributeWithEmptyComment.dll")])
+    
+
+    [<Test>]
+    [<Category("TypeProvider")>]
+    [<Category("TypeProvider.XmlDocAttribute")>]
+    //This is to test the correct TypeProvider Property message is shown or not in the TypeProviderXmlDocAttribute
+    member public this.``TypeProvider.XmlDocAttribute.Property.Comment``() = 
+        
+        let fileContents = """ 
+                                let p = N.T.StaticProp(*Marker*)"""
+
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContents, "StaticProp(*Marker*)",
+         "This is a synthetic *property* created by me for N.T",
+         addtlRefAssy = [System.IO.Path.Combine(System.Environment.CurrentDirectory, @"UnitTestsResources\MockTypeProviders\XmlDocAttributeWithAdequateComment.dll")])
+    
+    [<Test>]
+    [<Category("TypeProvider")>]
+    [<Category("TypeProvider.XmlDocAttribute")>]
+    //This is to test the multi-language in the TypeProviderXmlDocAttribute for TypeProvider Property
+    member public this.``TypeProvider.XmlDocAttribute.Property.LocalizedComment``() = 
+        
+        let fileContents = """ 
+                                let p = N.T.StaticProp(*Marker*)"""
+
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContents, "StaticProp(*Marker*)", 
+         "This is a synthetic *property* Localized!  ኤፍ ሻርፕ for N.T",
+         addtlRefAssy = [System.IO.Path.Combine(System.Environment.CurrentDirectory, @"UnitTestsResources\MockTypeProviders\XmlDocAttributeWithLocalizedComment.dll")])
+   
+    [<Test>]
+    [<Category("TypeProvider")>]
+    [<Category("TypeProvider.XmlDocAttribute")>]
+    //This is to test for long message in the TypeProviderXmlDocAttribute for TypeProvider Property
+    member public this.``TypeProvider.XmlDocAttribute.Property.WithLongComment``() = 
+        
+        let fileContents = """
+                                let p = N.T.StaticProp(*Marker*)"""
+
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContents, "StaticProp(*Marker*)",
+         "This is a synthetic *property* created by me for N.T. Which is used to test the tool tip of the typeprovider Property to check if it shows the right message or not.!",
+         addtlRefAssy = [System.IO.Path.Combine(System.Environment.CurrentDirectory, @"UnitTestsResources\MockTypeProviders\XmlDocAttributeWithLongComment.dll")])
+    
+    [<Test>]
+    [<Category("TypeProvider")>]
+    [<Category("TypeProvider.XmlDocAttribute")>]
+    //This is to test when the message is null in the TypeProviderXmlDocAttribute for TypeProvider Property
+    member public this.``TypeProvider.XmlDocAttribute.Property.WithNullComment``() = 
+        
+        let fileContents = """
+                                let p = N.T.StaticProp(*Marker*)"""
+
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContents, "StaticProp(*Marker*)",
+         "property N.T.StaticProp: decimal", 
+         addtlRefAssy = [System.IO.Path.Combine(System.Environment.CurrentDirectory, @"UnitTestsResources\MockTypeProviders\XmlDocAttributeWithNullComment.dll")])
+    
+    [<Test>]
+    [<Category("TypeProvider")>]    
+    [<Category("TypeProvider.XmlDocAttribute")>]
+    //This is to test when there is empty message from the TypeProviderXmlDocAttribute for TypeProvider Property
+    member public this.``TypeProvider.XmlDocAttribute.Property.WithEmptyComment``() =
+
+        let fileContents = """
+                                let p = N.T.StaticProp(*Marker*)"""
+        
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContents, "StaticProp(*Marker*)",
+         "property N.T.StaticProp: decimal",
+         addtlRefAssy = [System.IO.Path.Combine(System.Environment.CurrentDirectory, @"UnitTestsResources\MockTypeProviders\XmlDocAttributeWithEmptyComment.dll")])
+    
+
+    [<Test>]
+    [<Category("TypeProvider")>]
+    [<Category("TypeProvider.StaticParameters")>]
+    //This test case Verify that when Hover over foo the correct quickinfo is displayed for TypeProvider static parameter
+    //Dummy Type Provider exposes a parametric type (N1.T) that takes 2 static params (string * int)
+    member public this.``TypeProvider.StaticParameters.Correct``() =
+        
+        let fileContents = """ 
+                       type foo(*Marker*) = N1.T< const "Hello World",2>"""
+        
+        this.AssertQuickInfoContainsAtStartOfMarker(
+            fileContents,
+            marker = "foo(*Marker*)",
+            expected = "type foo = N1.T",
+            addtlRefAssy = [System.IO.Path.Combine(System.Environment.CurrentDirectory,@"UnitTestsResources\MockTypeProviders\DummyProviderForLanguageServiceTesting.dll")])
+
+    [<Test>]
+    [<Category("TypeProvider")>]
+    [<Category("TypeProvider.StaticParameters")>]
+    //This test case Verify that when Hover over foo the correct quickinfo is displayed
+    //Dummy Type Provider exposes a parametric type (N1.T) that takes 2 static params (string * int)
+    //As you can see this is "Negative Case" to check that when given invalid static Parameter quickinfo shows "type foo = obj"
+    member public this.``TypeProvider.StaticParameters.Negative.Invalid``() =
+
+        let fileContents = """                    
+                    type foo(*Marker*) = N1.T< const 100,2>"""
+
+        this.AssertQuickInfoContainsAtStartOfMarker(
+            fileContents,
+            marker = "foo(*Marker*)",
+            expected = "type foo",
+            addtlRefAssy = [System.IO.Path.Combine(System.Environment.CurrentDirectory,@"UnitTestsResources\MockTypeProviders\DummyProviderForLanguageServiceTesting.dll")])
+
+    [<Test>]
+    [<Category("TypeProvider")>]
+    [<Category("TypeProvider.StaticParameters")>]
+    //This test case Verify that when Hover over foo the XmlComment is shown in quickinfo
+    //Dummy Type Provider exposes a parametric type (N1.T) that takes 2 static params (string * int)
+    member public this.``TypeProvider.StaticParameters.XmlComment``() =
+              
+        let fileContents = """                    
+                    ///XMLComment
+                    type foo(*Marker*) = N1.T< const "Hello World",2>"""
+
+        this.AssertQuickInfoContainsAtStartOfMarker( 
+            fileContents,
+            marker = "foo(*Marker*)",
+            expected = "XMLComment",
+            addtlRefAssy = [System.IO.Path.Combine(System.Environment.CurrentDirectory,@"UnitTestsResources\MockTypeProviders\DummyProviderForLanguageServiceTesting.dll")])
+
+    [<Test>]
+    [<Category("TypeProvider")>]
+    [<Category("TypeProvider.StaticParameters")>]
+    member public this.``TypeProvider.StaticParameters.QuickInfo.OnTheErasedType``() =
+        let fileContents = """type TTT = Samples.FSharp.RegexTypeProvider.RegexTyped< @"(?<AreaCode>^\d{3})-(?<PhoneNumber>\d{3}-\d{7}$)">"""
+        this.AssertQuickInfoContainsAtStartOfMarker( 
+            fileContents,
+            marker = "TTT",
+            expected = "type TTT = Samples.FSharp.RegexTypeProvider.RegexTyped<...>\n\nFull name: File1.TTT",
+            addtlRefAssy = ["System"; System.IO.Path.Combine(System.Environment.CurrentDirectory,@"UnitTestsResources\MockTypeProviders\DummyProviderForLanguageServiceTesting.dll")])
+
+    [<Test>]
+    [<Category("TypeProvider")>]
+    [<Category("TypeProvider.StaticParameters")>]
+    member public this.``TypeProvider.StaticParameters.QuickInfo.OnNestedErasedTypeProperty``() =
+        let fileContents = """
+            type T = Samples.FSharp.RegexTypeProvider.RegexTyped< @"(?<AreaCode>^\d{3})-(?<PhoneNumber>\d{3}-\d{7}$)">
+            let reg = T() 
+            let r = reg.Match("425-123-2345").AreaCode.Value
+            """
+        this.AssertQuickInfoContainsAtStartOfMarker( 
+            fileContents,
+            marker = "reaCode.Val",
+            expected = """property Samples.FSharp.RegexTypeProvider.RegexTyped<...>.MatchType.AreaCode: System.Text.RegularExpressions.Group""",
+            addtlRefAssy = ["System"; System.IO.Path.Combine(System.Environment.CurrentDirectory,@"UnitTestsResources\MockTypeProviders\DummyProviderForLanguageServiceTesting.dll")])
+    
+    // Regression for 2948
+    [<Test>]
+    member public this.TypeRecordQuickInfo() = 
+      
+        let fileContents = """namespace NS
+                           type Re(*MarkerRecord*) = { X : int } """
+        let expectedQuickinfoTypeRecored = "type Re =  {X: int;}"
+        
+        this.InfoInDeclarationTestQuickInfoImplWithTrim fileContents "Re(*MarkerRecord*)" expectedQuickinfoTypeRecored
+    
+    [<Test>]
+    member public this.``QuickInfo.LetBindingsInTypes``() = 
+        let code = 
+            """
+            type A() = 
+                let fff n = n + 1                
+            """
+        this.AssertQuickInfoContainsAtEndOfMarker(code, "let ff", "val fff : (int -> int)")
+
+    // Regression for 2494
+    [<Test>]
+    member public this.TypeConstructorQuickInfo() = 
+      
+        let fileContents = """
+                            open System
+
+                            type PriorityQueue(*MarkerType*)<'k,'a> =
+                              | Nil(*MarkerDataConstructor*)
+                              | Branch of 'k * 'a * PriorityQueue<'k,'a> * PriorityQueue<'k,'a>
+  
+                            module PriorityQueue(*MarkerModule*) =
+                              let empty = Nil
+  
+                              let minKeyValue = function
+                                | Nil             -> failwith "empty queue"
+                                | Branch(k,a,_,_) -> (k,a)
+    
+                              let minKey pq = fst (minKeyValue pq(*MarkerVal*))
+  
+                              let singleton(*MarkerLastLine*) k a = Branch(k,a,Nil,Nil)
+                            """
+        //Verify the quick info as expected
+        let expectedquickinfoPriorityQueue = "type PriorityQueue<'k,'a> =  | Nil  | Branch of 'k * 'a * PriorityQueue<'k,'a> * PriorityQueue<'k,'a>"
+        let expectedquickinfoNil = "union case PriorityQueue.Nil: PriorityQueue<'k,'a>"
+        let expectedquickinfoPriorityQueueinModule = "module PriorityQueue\n\nfrom File1"
+        let expectedquickinfoVal = "val pq : PriorityQueue<'a,'b>"
+        let expectedquickinfoLastLine = "val singleton : k:'a -> a:'b -> PriorityQueue<'a,'b>"
+
+        this.InfoInDeclarationTestQuickInfoImplWithTrim fileContents "PriorityQueue(*MarkerType*)" expectedquickinfoPriorityQueue
+        this.InfoInDeclarationTestQuickInfoImplWithTrim fileContents "Nil(*MarkerDataConstructor*)" expectedquickinfoNil
+        this.InfoInDeclarationTestQuickInfoImplWithTrim fileContents "PriorityQueue(*MarkerModule*)" expectedquickinfoPriorityQueueinModule
+        this.InfoInDeclarationTestQuickInfoImplWithTrim fileContents "pq(*MarkerVal*)" expectedquickinfoVal
+        this.InfoInDeclarationTestQuickInfoImplWithTrim fileContents "singleton(*MarkerLastLine*)" expectedquickinfoLastLine
+        
+    [<Test>]
+    member public this.NamedDUFieldQuickInfo() = 
+      
+        let fileContents = """
+                            type NamedFieldDU(*MarkerType*) =
+                              | Case1(*MarkerCase1*) of V1 : int * bool * V3 : float
+                              | Case2(*MarkerCase2*) of ``Big Name`` : int * Item2 : bool
+                              | Case3(*MarkerCase3*) of Item : int
+                              
+                            exception NamedExn(*MarkerException*) of int * V2 : string * bool * Data9 : float
+                            """
+        //Verify the quick info as expected
+        let expectedquickinfoType = "type NamedFieldDU =  | Case1 of V1: int * bool * V3: float  | Case2 of Big Name: int * bool  | Case3 of int"
+        let expectedquickinfoCase1 = "union case NamedFieldDU.Case1: V1: int * bool * V3: float -> NamedFieldDU"
+        let expectedquickinfoCase2 = "union case NamedFieldDU.Case2: Big Name: int * bool -> NamedFieldDU"
+        let expectedquickinfoCase3 = "union case NamedFieldDU.Case3: int -> NamedFieldDU"
+        let expectedquickinfoException = "exception NamedExn of int * V2: string * bool * Data9: float"
+
+        this.InfoInDeclarationTestQuickInfoImplWithTrim fileContents "NamedFieldDU(*MarkerType*)" expectedquickinfoType
+        this.InfoInDeclarationTestQuickInfoImplWithTrim fileContents "Case1(*MarkerCase1*)" expectedquickinfoCase1
+        this.InfoInDeclarationTestQuickInfoImplWithTrim fileContents "Case2(*MarkerCase2*)" expectedquickinfoCase2
+        this.InfoInDeclarationTestQuickInfoImplWithTrim fileContents "Case3(*MarkerCase3*)" expectedquickinfoCase3
+        this.InfoInDeclarationTestQuickInfoImplWithTrim fileContents "NamedExn(*MarkerException*)" expectedquickinfoException
+
+    [<Test>]
+    member public this.``EnsureNoAssertFromBadParserRangeOnAttribute``() = 
+        let fileContents = """ 
+                [<System.Obsolete>]
+                Types foo = int"""
+        this.AssertQuickInfoContainsAtEndOfMarker (fileContents, "ype", "")  // just want to ensure there is no assertion fired by the parse tree walker
+   
+    [<Test>]
+    member public this.``ShiftKeyDown``() =
+        ShiftKeyDown(this.VS)
+        this.AssertQuickInfoContainsAtEndOfMarker 
+          ("""#light""","#ligh","")
+
+    [<Test>]
+    member public this.``ActivePatterns.Declaration``() =        
+        this.AssertQuickInfoContainsAtEndOfMarker 
+          ("""let ( |One|Two| ) x = One(x+1)""","ne|Tw","int -> Choice")
+
+    [<Test>]
+    member public this.``ActivePatterns.Result``() =        
+        this.AssertQuickInfoContainsAtEndOfMarker 
+          ("""let ( |One|Two| ) x = One(x+1)""","= On","active pattern result One: int -> Choice")
+
+
+    [<Test>]
+    member public this.``ActivePatterns.Value``() =        
+        this.AssertQuickInfoContainsAtEndOfMarker 
+         ("""let ( |One|Two| ) x = One(x+1)
+             let patval = (|One|Two|) // use""","= (|On","int -> Choice")
+          
+    [<Test>]
+    member public this.``Regression.InDeclaration.Bug3176a``() =        
+        this.AssertQuickInfoContainsAtEndOfMarker 
+          ("""type T<'a> = { aaaa : 'a; bbbb : int } ""","aa","aaaa")
+
+    [<Test>]
+    member public this.``Regression.InDeclaration.Bug3176c``() =        
+        this.AssertQuickInfoContainsAtEndOfMarker 
+          ("""type C =
+                val aaaa : int""","aa","aaaa")
+                      
+    [<Test>]
+    member public this.``Regression.InDeclaration.Bug3176d``() =        
+        this.AssertQuickInfoContainsAtEndOfMarker 
+          ("""type DU<'a> =
+                | DULabel of 'a""","DULab","DULabel")
+
+    [<Test>]
+    member public this.``Regression.Generic.3773a``() =        
+        this.AssertQuickInfoContainsAtEndOfMarker 
+          ("""let rec M2<'a>(a:'a) = M2(a)""","let rec M","val M2 : a:'a -> obj")
+
+    // Before this fix, if the user hovered over 'cccccc' they would see 'Yield'
+    [<Test>]
+    member public this.``Regression.ComputationExpressionMemberAppearingInQuickInfo``() =        
+        this.VerifyQuickInfoDoesNotContainAnyAtEndOfMarker 
+            """
+                module Test
+                let q2 = 
+                    query { 
+                        for p in [1;2] do            
+                            join cccccc in [3;4] on (p = cccccc)
+                            yield cccccc
+                    }"""
+            "yield ccc" "Yield"
+          
+    // Before this fix, if the user hovered over get or set in a property then
+    // they would see a quickinfo for any available function named get or set.
+    // The tests below define a get function with 'let' and then test to make sure that
+    // this isn't the get seen in the tool tip.
+    [<Test>]
+    member public this.``Regression.AccessorMutator.Bug4903a``() =        
+        this.VerifyQuickInfoDoesNotContainAnyAtEndOfMarker 
+            """namespace CountChocula
+               type BooBerry() =
+                   let get() = ""
+                   member source.Prop
+                       with get() : int = 0
+                       and set(value:int) : unit = ()""" 
+            "with g" "string"
+          
+    [<Test>]
+    member public this.``Regression.AccessorMutator.Bug4903d``() =        
+        this.VerifyQuickInfoDoesNotContainAnyAtEndOfMarker 
+            """namespace CountChocula
+               type BooBerry() =
+                   member source.AMethod() = ()
+                   member source.AProperty
+                       with get() : int = 0
+                       and set(value:int) : unit = ()""" 
+            "AMetho" "string"          
+          
+    [<Test>]
+    member public this.``Regression.AccessorMutator.Bug4903b``() =        
+        this.VerifyQuickInfoDoesNotContainAnyAtEndOfMarker 
+            """namespace CountChocula
+               type BooBerry() =
+                   let get() = ""
+                   member source.Prop
+                       with get() : int = 0
+                       and set(value:int) : unit = ()"""
+            "and s" "seq"          
+          
+    [<Test>]
+    member public this.``Regression.AccessorMutator.Bug4903c``() =        
+        this.AssertQuickInfoContainsAtEndOfMarker 
+           ("""namespace CountChocula
+               type BooBerry() =
+                   let get() = ""
+                   member source.Prop
+                       with get() : int = 0
+                       and set(value:int) : unit = ()""",
+            "let g","string")
+          
+
+    [<Test>]
+    member public this.``ParamsArrayArgument.OnType``() =        
+        this.AssertQuickInfoContainsAtEndOfMarker 
+           ("""
+                type A() =
+                    static member Foo([<System.ParamArrayAttribute>] a : int[]) = ()
+                let r = A.Foo(42)""" ,
+            "type A","params a:"    )
+
+    [<Test>]
+    member public this.``ParamsArrayArgument.OnMethod``() =        
+        this.AssertQuickInfoContainsAtEndOfMarker 
+           ("""
+                type A() =
+                    static member Foo([<System.ParamArrayAttribute>] a : int[]) = ()
+                let r = A.Foo(42)""" ,
+            "A.Foo","params a:"    )
+          
+    [<Test>]
+    member public this.``Regression.AccessorMutator.Bug4903e``() =        
+        this.AssertQuickInfoContainsAtEndOfMarker 
+           ("""namespace CountChocula
+               type BooBerry() =
+                   let get() = ""
+                   member source.Prop
+                       with get() : int = 0
+                       and set(value:int) : unit = ()""" ,
+            "member source.Pr","Prop"    )
+          
+    [<Test>]
+    member public this.``Regression.AccessorMutator.Bug4903f``() =        
+        this.AssertQuickInfoContainsAtEndOfMarker 
+           ("""namespace CountChocula
+               type BooBerry() =
+                   let get() = ""
+                   member source.Prop
+                       with get() : int = 0
+                       and set(value:int) : unit = ()""" ,
+            "member source.Pr","int"                   )
+          
+    [<Test>]
+    member public this.``Regression.AccessorMutator.Bug4903g``() =        
+        this.AssertQuickInfoContainsAtEndOfMarker 
+           ("""namespace CountChocula
+               type BooBerry() =
+                   let get() = ""
+                   member source.Prop
+                       with get() : int = 0
+                       and set(value:int) : unit = ()""" ,
+            "member sou","source"                )
+
+    [<Test>]
+    member public this.``Regression.RecursiveDefinition.Generic.3773b``() =        
+        this.AssertQuickInfoContainsAtEndOfMarker 
+          ("""let rec M1<'a>(a:'a) = M1(0)""","let rec M","val M1 : a:int -> 'a")
+          
+        //regression test for bug Dev11:138110 - "F# language service hover tip for ITypeProvider does now show Invalidate event"
+    [<Test>]
+    member public this.``Regression.ImportedEvent.138110``() =
+        let fileContents = """
+open Microsoft.FSharp.Core.CompilerServices
+let f (tp:ITypeProvider(*$$$*)) = tp.Invalidate
+                           """
+        this.AssertQuickInfoContainsAtStartOfMarker(
+            fileContents, 
+            "Provider(*$$$*)", 
+            "Invalidate", addtlRefAssy=standard40AssemblyRefs ) //"FSharp.Core" add the reference in SxS will cause build failure and intellisense broken, the dll is added by default
+
+
+
+    [<Test>]
+    member public this.``Declaration.CyclicalDeclarationDoesNotCrash``() =
+        this.AssertQuickInfoContainsAtEndOfMarker
+          ("""type (*1*)A = int * (*2*)A ""","(*2*)","type A")
+
+    [<Test>]
+    member public this.``JustAfterIdentifier``() =
+        this.AssertQuickInfoContainsAtEndOfMarker
+          ("""let f x = x + 1 ""","let f","int")
+        
+    [<Test>]
+    member public this.``FrameworkClass``() =
+        let fileContent = """let l = new System.Collections.Generic.List<int>()"""
+        let marker = "Generic.List"
+        this.AssertQuickInfoContainsAtEndOfMarker(fileContent,marker,"member Capacity : int with get, set\n")
+        this.AssertQuickInfoContainsAtEndOfMarker(fileContent,marker,"member Clear : unit -> unit\n")
+        //this.AssertQuickInfoContainsAtEndOfMarker(fileContent,marker,"member Item : int -> 'T with get, set\n") // removed because quickinfo is now smaller
+        this.VerifyQuickInfoDoesNotContainAnyAtEndOfMarker fileContent marker "get_Capacity"
+        this.VerifyQuickInfoDoesNotContainAnyAtEndOfMarker fileContent marker "set_Capacity"
+        this.VerifyQuickInfoDoesNotContainAnyAtEndOfMarker fileContent marker "get_Count"
+        this.VerifyQuickInfoDoesNotContainAnyAtEndOfMarker fileContent marker "set_Count"
+          
+    [<Test>]
+    member public this.``FrameworkClassNoMethodImpl``() =
+        this.VerifyQuickInfoDoesNotContainAnyAtEndOfMarker
+          """let l = new System.Collections.Generic.LinkedList<int>()"""
+           "Generic.LinkedList" "System.Collections.ICollection.ISynchronized" // Bug 5092: A framework class contained a private method impl
+
+    [<Test>]
+    member public this.``Regression.ModulesFromExternalLibrariesBug5785``() =
+        use _guard = this.UsingNewVS()
+        let solution = this.CreateSolution()
+        let projectLib = CreateProject(solution,"testlib")
+        let file = AddFileFromText(projectLib,"MyLibrary.fs", 
+                      [ "module MyLibrary"
+                        "let x = 1"
+                        "module Nested ="
+                        "    let y = 2"
+                        "    module Deeper ="
+                        "        let z = 3"
+                      ])
+        let project = CreateProject(solution,"testapp")
+        let file = AddFileFromText(project,"App.fs", 
+                      [ "let a = MyLibrary.Nested.Deeper.z" ])
+        SetConfigurationAndPlatform(project, "Debug|AnyCPU")  // we must set config/platform when building with ProjectReferences
+        SetConfigurationAndPlatform(projectLib, "Debug|AnyCPU")  // we must set config/platform when building with ProjectReferences
+        AddProjectReference(project, projectLib)
+        let br = BuildTarget(projectLib, "Build") // build the dependent library
+        Assert.IsTrue(br.BuildSucceeded, "build should succeed")
+        let file = OpenFile(project,"App.fs")
+        TakeCoffeeBreak(this.VS) // Wait for the background compiler to catch up.
+
+        let gpatcc = GlobalParseAndTypeCheckCounter.StartNew(this.VS)
+
+        ShiftKeyUp(this.VS)
+        MoveCursorToEndOfMarker(file, "MyLi")
+        let tooltip = time1 GetQuickInfoAtCursor file "Time of first tooltip"
+        AssertMatchesRegex '\n' "module MyLibrary\n[Filename:.*\bin\Debug\testlib.exe]\n[Signature:T:MyLibrary]" tooltip  
+
+        MoveCursorToEndOfMarker(file, "Nes")
+        let tooltip = time1 GetQuickInfoAtCursor file "Time of first tooltip"
+        AssertMatchesRegex '\n' "module Nested\n\nfrom MyLibrary\n[Filename:.*\bin\Debug\testlib.exe]\n[Signature:T:MyLibrary.Nested]" tooltip
+
+        MoveCursorToEndOfMarker(file, "Dee")
+        let tooltip = time1 GetQuickInfoAtCursor file "Time of first tooltip"
+        AssertMatchesRegex '\n' "module Deeper\n\nfrom MyLibrary.Nested\n[Filename:.*\bin\Debug\testlib.exe]\n[Signature:T:MyLibrary.Nested]" tooltip
+
+        gpatcc.AssertExactly(0,0)
+            
+    (* ------------------------------------------------------------------------------------- *)
+
+
+    /// Even though we don't show squiggles, some types will still be known. For example, System.String.
+    [<Test>]
+    member public this.``OrphanFs.BaselineIntellisenseStillWorks``() = 
+        this.AssertQuickInfoContainsAtEndOfMarker
+           ("""let astring = "Hello" ""","let astr","string")
+
+    /// FEATURE: User may hover over a type or identifier and get basic information about it in a tooltip.
+    [<Test>]
+    member public this.``Basic``() = 
+        let fileContent = """type (*bob*)Bob() = 
+                                  let x = 1"""
+        let marker = "(*bob*)"
+        this.AssertQuickInfoContainsAtEndOfMarker(fileContent,marker,"Bob =")
+        this.AssertQuickInfoContainsAtEndOfMarker(fileContent,marker,"Bob =")
+
+    [<Test>]
+    member public this.``ModuleDefinition.ModuleNoNewLines``() = 
+        let fileContent = """module XXX
+                             type t = C3
+                             module YYY =
+                                type t = C4
+                             ///Doc
+                             module ZZZ =
+                                type t = C5 """
+        // The <summary> arises because the xml doc mechanism places these before handing them to VS for processing.
+        this.AssertQuickInfoContainsAtEndOfMarker(fileContent,"XX","module XXX")
+        this.AssertQuickInfoContainsAtEndOfMarker(fileContent,"YY","module YYY\n\nfrom XXX")
+        this.AssertQuickInfoContainsAtEndOfMarker(fileContent,"ZZ","module ZZZ\n\nfrom XXX\n<summary>\n\nDoc</summary>")
+
+    [<Test>]
+    member public this.``IdentifierWithTick``() = 
+        let code = 
+                                    ["#light"
+                                     "let x = 1"
+                                     "let x' = \"foo\""
+                                     "if (*aaa*)x = 1 then (*bbb*)x' else \"\""
+                                     ]
+        let (_, _, file) = this.CreateSingleFileProject(code)
+        MoveCursorToEndOfMarker(file,"(*aaa*)")
+        let tooltip = GetQuickInfoAtCursor file
+        AssertContains(tooltip,"val x : int")
+
+        MoveCursorToEndOfMarker(file,"(*bbb*)")
+        let tooltip = GetQuickInfoAtCursor file
+        AssertContains(tooltip,"val x' : string")
+
+    [<Test>]
+    member public this.``NegativeTest.CharLiteralNotConfusedWithIdentifierWithTick``() = 
+        let fileContent = """let x = 1"
+                             let y = 'x' """
+        this.AssertQuickInfoContainsAtEndOfMarker(fileContent,"'x","")   // no tooltips for char literals
+
+    [<Test>]
+    member public this.``QueryExpression.QuickInfoSmokeTest1``() = 
+        let fileContent = """let q = query { for x in ["1"] do select x }"""
+        this.AssertQuickInfoContainsAtEndOfMarker(fileContent,"selec","custom operation: select", addtlRefAssy=standard40AssemblyRefs)
+        this.AssertQuickInfoContainsAtEndOfMarker(fileContent,"selec","custom operation: select ('Result)"   , addtlRefAssy=standard40AssemblyRefs)
+        this.AssertQuickInfoContainsAtEndOfMarker(fileContent,"selec","Calls"   , addtlRefAssy=standard40AssemblyRefs)
+        this.AssertQuickInfoContainsAtEndOfMarker(fileContent,"selec","Linq.QueryBuilder.Select"  , addtlRefAssy=standard40AssemblyRefs )
+
+    [<Test>]
+    member public this.``QueryExpression.QuickInfoSmokeTest2``() = 
+        let fileContent = """let q = query { for x in ["1"] do join y in ["2"] on (x = y); select (x,y) }"""
+        this.AssertQuickInfoContainsAtEndOfMarker(fileContent,"joi","custom operation: join"  , addtlRefAssy=standard40AssemblyRefs )
+        this.AssertQuickInfoContainsAtEndOfMarker(fileContent,"joi","join var in collection on (outerKey = innerKey)"   , addtlRefAssy=standard40AssemblyRefs)
+        this.AssertQuickInfoContainsAtEndOfMarker(fileContent,"joi","Calls"  , addtlRefAssy=standard40AssemblyRefs )
+        this.AssertQuickInfoContainsAtEndOfMarker(fileContent,"joi","Linq.QueryBuilder.Join"  , addtlRefAssy=standard40AssemblyRefs )
+
+    [<Test>]
+    member public this.``QueryExpression.QuickInfoSmokeTest3``() = 
+        let fileContent = """let q = query { for x in ["1"] do groupJoin y in ["2"] on (x = y) into g; select (x,g) }"""
+        this.AssertQuickInfoContainsAtEndOfMarker(fileContent,"groupJoin","custom operation: groupJoin"  , addtlRefAssy=standard40AssemblyRefs )
+        this.AssertQuickInfoContainsAtEndOfMarker(fileContent,"groupJoin","groupJoin var in collection on (outerKey = innerKey)"   , addtlRefAssy=standard40AssemblyRefs)
+        this.AssertQuickInfoContainsAtEndOfMarker(fileContent,"groupJoin","Calls"  , addtlRefAssy=standard40AssemblyRefs )
+        this.AssertQuickInfoContainsAtEndOfMarker(fileContent,"groupJoin","Linq.QueryBuilder.GroupJoin"   , addtlRefAssy=standard40AssemblyRefs)
+
+
+    /// Hovering over a literal string should not show data tips for variable names that appear in the string
+    [<Test>]
+    member public this.``StringLiteralWithIdentifierLookALikes.Bug2360_A``() =
+        let fileContent = """let y = 1
+                             let f x = "x"
+                             let g z = "y" """
+        this.VerifyQuickInfoDoesNotContainAnyAtEndOfMarker fileContent "f x = \"" "val"
+
+    /// Hovering over a literal string should not show data tips for variable names that appear in the string
+    [<Test>]
+    member public this.``Regression.StringLiteralWithIdentifierLookALikes.Bug2360_B``() =
+        let fileContent = """let y = 1"""
+        this.AssertQuickInfoContainsAtEndOfMarker(fileContent,"let ","int")
+
+    /// FEATURE: Intellisense information from types in earlier files in the project is available in subsequent files.        
+    [<Test>]
+    member public this.``AcrossMultipleFiles``() =
+        use _guard = this.UsingNewVS()
+        let solution = this.CreateSolution()
+        let project = CreateProject(solution,"testproject")
+        let file1 = AddFileFromText(project,"File1.fs",
+                                    ["#light"
+                                     "type Bob() = "
+                                     "    let x = 1"])
+        let file2 = AddFileFromText(project,"File2.fs",
+                                    ["#light"
+                                     "let bob = new File1.Bob()"])
+        let file1 = OpenFile(project,"File1.fs")
+        let file2 = OpenFile(project,"File2.fs")
+        
+        // Get the tooltip at type Bob        
+        MoveCursorToEndOfMarker(file2,"let bo")
+        let tooltip = time1 GetQuickInfoAtCursor file2 "Time of first tooltip"
+        printf "First-%s\n" tooltip
+        AssertContains(tooltip,"File1.Bob")
+        
+        // Get the tooltip again
+        MoveCursorToEndOfMarker(file2,"let bo")
+        let tooltip = time1 GetQuickInfoAtCursor file2 "Time of second tooltip"
+        printf "Second-%s\n" tooltip
+        AssertContains(tooltip,"File1.Bob")
+
+    /// FEATURE: Linked files work
+    [<Test>]
+    member public this.``AcrossLinkedFiles``() =
+        use _guard = this.UsingNewVS()
+        let solution = this.CreateSolution()
+        let project = CreateProject(solution,"testproject")
+        let file1 = AddLinkedFileFromTextEx(project, @"..\LINK.FS", @"..\link.fs", @"MyLink.fs",
+                                    ["#light"
+                                     "type Bob() = "
+                                     "    let x = 1"])
+        let file2 = AddFileFromText(project,"File2.fs",
+                                    ["#light"
+                                     "let bob = new Link.Bob()"])
+        let file1 = OpenFile(project, @"..\link.fs")
+        let file2 = OpenFile(project, @"File2.fs")
+        
+        // Get the tooltip at type Bob        
+        MoveCursorToEndOfMarker(file2,"let bo")
+        let tooltip = time1 GetQuickInfoAtCursor file2 "Time of first tooltip"
+        printf "First-%s\n" tooltip
+        AssertContains(tooltip,"Link.Bob")
+        
+        // Get the tooltip again
+        MoveCursorToEndOfMarker(file2,"let bo")
+        let tooltip = time1 GetQuickInfoAtCursor file2 "Time of second tooltip"
+        printf "Second-%s\n" tooltip
+        AssertContains(tooltip,"Link.Bob")
+
+    [<Test>]
+    member public this.``TauStarter``() =
+        let code =
+                                    ["#light"
+                                     "type (*Scenario01*)Bob() ="
+                                     "    let x = 1"
+                                     "type (*Scenario021*)Bob ="
+                                     "    class"
+                                     "    public new() = { }"
+                                     "end"
+                                     "type (*Scenario022*)Alice ="
+                                     "    class"
+                                     "    public new() = { }" 
+                                     "end"]
+        let (_, _, file) = this.CreateSingleFileProject(code)
+        TakeCoffeeBreak(this.VS) 
+
+        MoveCursorToEndOfMarker(file,"(*Scenario021*)")
+        let tooltip = time1 GetQuickInfoAtCursor file "Time of first tooltip"
+        printf "First-%s\n" tooltip
+        Assert.IsTrue(tooltip.Contains("Bob ="))
+        
+        MoveCursorToEndOfMarker(file,"(*Scenario022*)")
+        let tooltip = time1 GetQuickInfoAtCursor file "Time of first tooltip"
+        printf "First-%s\n" tooltip
+        Assert.IsTrue(tooltip.Contains("Alice ="))
+
+    member private this.QuickInfoResolutionTest lines queries =
+        let code = [ yield "#light"
+                     yield! lines ]
+        let (_, _, file) = this.CreateSingleFileProject(code)
+        TakeCoffeeBreak(this.VS) 
+
+
+        // Move along the entire length of the identifier checking that the tooltip text contains something familiar
+        for (initial,ident:string,expectedText) in queries do
+            for i in 0..ident.Length-1 do
+                let marker = initial+ident.[0..i-1]
+                MoveCursorToEndOfMarker(file,marker)
+                let tooltip = time1 GetQuickInfoAtCursor file "Time for tooltip"
+                printf "QuickInfo at marker '%s' is '%s', expect '%s'\n" marker tooltip expectedText
+                Assert.IsTrue(tooltip.Contains(expectedText))
+
+    member public this.GetLongPathsTestCases() =
+            ["let test0 = System.Console.In"
+             "let test0b = System.Collections.Generic.List<int>()"
+             "let test0c = System.Collections.Generic.KeyNotFoundException()"
+             "type Test0d = System.Collections.Generic.List<int>"
+             "type Test0e = System.Collections.Generic.KeyNotFoundException"],
+        
+              // The quick info specification                                    // Some of the expected quick info text
+             [("let test0 = ","System"                                           ,"namespace System"); 
+              ("let test0 = System.","Console"                                   ,"Console =");  
+              ("let test0 = System.Console.","In"                                ,"System.Console.In");  
+              ("let test0 = System.Console.","In"                                ,"TextReader");  
+              ("let test0b = ","System"                                          ,"namespace System"); 
+              ("let test0b = System.","Collections"                              ,"namespace System.Collections");  
+              ("let test0b = System.Collections.","Generic"                      ,"namespace System.Collections.Generic");  
+              ("let test0b = System.Collections.Generic.","List"                 ,"List()"); // note resolves to constructor  
+              ("let test0c = ","System"                                          ,"namespace System"); 
+              ("let test0c = System.","Collections"                              ,"namespace System.Collections");  
+              ("let test0c = System.Collections.","Generic"                      ,"namespace System.Collections.Generic");  
+              ("let test0c = System.Collections.Generic.","KeyNotFoundException" ,"KeyNotFoundException()");  // note resolves to constructor  
+              ("type Test0d = ","System"                                         ,"namespace System"); 
+              ("type Test0d = System.","Collections"                             ,"namespace System.Collections");  
+              ("type Test0d = System.Collections.","Generic"                     ,"namespace System.Collections.Generic");  
+              ("type Test0d = System.Collections.Generic.","List"                ,"Generic.List"); // note resolves to type
+              ("type Test0e = ","System"                                         ,"namespace System"); 
+              ("type Test0e = System.","Collections"                             ,"namespace System.Collections");  
+              ("type Test0e = System.Collections.","Generic"                     ,"namespace System.Collections.Generic");  
+              ("type Test0e = System.Collections.Generic.","KeyNotFoundException","Generic.KeyNotFoundException");  // note resolves to type
+             ]
+        
+    [<Test>]
+    [<Category("TakesMoreThanFifteenSeconds")>]
+    member public this.``LongPaths``() =
+        let text,cases = this.GetLongPathsTestCases()
+        this.QuickInfoResolutionTest text cases
+
+    [<Test>]
+    [<Category("TakesMoreThanFifteenSeconds")>]
+    member public this.``Global.LongPaths``() =
+        let text,cases = this.GetLongPathsTestCases()
+        let replace (s:string) = s.Replace("System", "global.System")
+        let text = text |> List.map (fun s -> replace s) 
+        let cases = 
+           cases 
+               |> List.filter (fun (a,_,_) -> a.Contains "System") 
+               |> List.map (fun (a,b,expectedResult) -> replace a, replace b, expectedResult)
+
+        this.QuickInfoResolutionTest text cases
+        
+    [<Test>]
+    member public this.``TypeAndModuleReferences``() =
+        this.QuickInfoResolutionTest 
+            ["let test1 = List.length"
+             "let test2 = List.Empty"
+             "let test3 = (\"1\").Length"
+             "let test3b = (id \"1\").Length"]
+
+            // The quick info specification                                    // Some of the expected quick info text
+           [("let test1 = ","List"                                             ,"module List");  
+            ("let test1 = List.","length"                                      ,"length");  
+            ("let test2 = ","List"                                             ,"Collections.List");  
+            ("let test2 = List.","Empty"                                       ,"List.Empty");
+            ("let test3 = (\"1\").","Length"                                   ,"String.Length");
+            ("let test3b = (id \"1\").","Length"                               ,"String.Length") ]
+        
+    [<Test>]
+    member public this.``ModuleNameAndMisc``() =
+        this.QuickInfoResolutionTest 
+            ["module (*test3q*)MM3 ="
+             "    let y = 2"
+             "let test4 = lock";
+             "let (*test5*) ffff xx = xx + 1" ]
+
+            // The quick info specification                                    // Some of the expected quick info text
+           [("module (*test3q*)","MM3"                                         ,"module MM3");
+            ("let test4 = ","lock"                                             ,"lock");
+            ("let (*test5*) ","ffff"                                           ,"ffff") ]
+
+    [<Test>]
+    member public this.``MemberIdentifiers``() =
+        this.QuickInfoResolutionTest 
+            ["type TestType() ="
+             "     member (*test6*) xx.PPPP = 1"
+             "     member (*test7*) xx.QQQQ(x) = 3.0"
+             "let test8 = (TestType()).PPPP"]
+
+            // The quick info specification                                    // Some of the expected quick info text
+           [("member (*test6*) ","xx"                                          ,"TestType");
+            ("member (*test6*) xx.","PPPP"                                     ,"PPPP");
+            ("member (*test7*) ","xx"                                          ,"TestType");
+            ("member (*test7*) xx.","QQQQ"                                     ,"float");
+            ("member (*test7*) xx.","QQQQ"                                     ,"float");
+            ("let test8 = (TestType()).", "PPPP"                               , "PPPP") ]
+        
+    [<Test>]
+    member public this.``IdentifiersForFields``() =
+        this.QuickInfoResolutionTest 
+            ["type TestType9 = { XXX : int }"
+             "let test11 = { XXX = 1 }"]
+
+            // The quick info specification                                    // Some of the expected quick info text
+           [("type TestType9 = { ", "XXX"                                      , "XXX: int");
+            ("let test11 = { ", "XXX"                                          , "XXX");] 
+        
+    [<Test>]
+    member public this.``IdentifiersForUnionCases``() =
+        this.QuickInfoResolutionTest 
+            ["type TestType10 = Case1 | Case2 of int"
+             "let test12 = (Case1,Case2(3))"]
+
+            // The quick info specification                                    // Some of the expected quick info text
+           [("type TestType10 = ", "Case1"                                     , "union case TestType10.Case1");
+            ("type TestType10 = Case1 | ", "Case2"                             , "union case TestType10.Case2");
+            ("let test12 = (", "Case1"                                         , "union case TestType10.Case1");
+            ("let test12 = (Case1,", "Case2"                                   , "union case TestType10.Case2");] 
+        
+    [<Test>]
+    member public this.``IdentifiersInAttributes``() =
+        this.QuickInfoResolutionTest 
+            ["[<(*test13*)System.CLSCompliant(true)>]"
+             "let test13 = 1"
+             "open System"
+             "[<(*test14*)CLSCompliant(true)>]"
+             "let test14 = 1"]
+
+            // The quick info specification                                    // Some of the expected quick info text
+           [("[<(*test13*)", "System"                                          , "namespace System");
+            ("[<(*test13*)System.", "CLSCompliant"                             , "CLSCompliantAttribute");
+            ("[<(*test14*)", "CLSCompliant"                                    , "CLSCompliantAttribute");] 
+        
+    [<Test>]
+    member public this.``ArgumentAndPropertyNames``() =
+        this.QuickInfoResolutionTest 
+            ["type R = { mutable AAA : int }"
+             "         static member M() = { AAA = 1 }" 
+             "let test13 = R.M(AAA=3)"
+             "type R2() = "
+             "    static member M() = System.Reflection.InterfaceMapping()"
+             ""
+             "let test14 = R2.M(InterfaceMethods= [| |])"
+             ""
+             "let test15 = new System.Reflection.AssemblyName(Name=\"Foo\")"
+             "let test16 = new System.Reflection.AssemblyName(assemblyName=\"Foo\")"]
+
+            // The quick info specification                                    // Some of the expected quick info text
+           [("let test13 = R.M(", "AAA"        , "R.AAA: int");
+            ("let test14 = R2.M(", "InterfaceMethods"        , "field System.Reflection.InterfaceMapping.InterfaceMethods");
+            ("let test15 = new System.Reflection.AssemblyName(", "Name"        , "property System.Reflection.AssemblyName.Name");
+            ("let test16 = new System.Reflection.AssemblyName(", "assemblyName", "argument assemblyName")] 
+        
+    /// Quickinfo was throwing an exception when the mouse was over the end of a line.
+    [<Test>]
+    member public this.``AtEndOfLine``() =
+        let fileContent = """#light"""
+        this.VerifyQuickInfoDoesNotContainAnyAtEndOfMarker fileContent "#light" "Bug:"
+        
+    [<Test>]
+    member public this.``Regression.FieldRepeatedInToolTip.Bug3538``() = 
+        this.AssertIdentifierInToolTipExactlyOnce
+          """#light
+             open System.Runtime.InteropServices
+             [<StructLayout(LayoutKind.Explicit)>]
+             type A() = 
+               [<DefaultValue>]
+               val mutable x : int"""
+             "LayoutKind.Expl" "Explicit"
+
+    [<Test>]
+    member public this.``Regression.FieldRepeatedInToolTip.Bug3818``() = 
+        this.AssertIdentifierInToolTipExactlyOnce
+          """#light
+             [<System.AttributeUsage(System.AttributeTargets.All, Inherited = false)>]
+             type A() = 
+               do ()"""
+             "Inherite" "Inherited"  // Get the tooltip at "Inherite" & Verify that it contains the 'Inherited' fild exactly once
+        
+    [<Test>]
+    member public this.``MethodAndPropTooltip``() = 
+        let fileContent = """#light
+                             open System
+                             do
+                               Console.Clear()
+                               Console.BackgroundColor |> ignore"""
+        this.AssertIdentifierInToolTipExactlyOnce fileContent "Console.Cle" "Clear"
+        this.AssertIdentifierInToolTipExactlyOnce fileContent "Console.Back" "BackgroundColor"
+        
+    [<Test>]
+    member public this.``Regression.StaticVsInstance.Bug3626``() = 
+        let fileContent = """
+                             type Foo() =
+                                 member this.Bar () = "hllo"
+                                 static member Bar() = 13
+                             let z = (*int*) Foo.Bar()
+                             let Hoo = new Foo()
+                             let y = (*string*) Hoo.Bar() """
+        // Get the tooltip at "Foo.Bar("
+        this.AssertQuickInfoContainsAtEndOfMarker(fileContent,"(*int*) Foo.Ba","Foo.Bar")
+        this.AssertQuickInfoContainsAtEndOfMarker(fileContent,"(*int*) Foo.Ba","-> int")
+        // Get the tooltip at "Hoo.Bar("
+        this.AssertQuickInfoContainsAtEndOfMarker(fileContent,"(*string*) Hoo.Ba","Foo.Bar")
+        this.AssertQuickInfoContainsAtEndOfMarker(fileContent,"(*string*) Hoo.Ba","-> string")
+
+    [<Test>]
+    member public this.``Class.OnlyClassInfo``() = 
+        let fileContent = """type TT(x : int, ?y : int) = 
+                                 class end"""
+
+        this.AssertQuickInfoContainsAtEndOfMarker(fileContent,"type T","type TT")
+        this.VerifyQuickInfoDoesNotContainAnyAtEndOfMarker fileContent "type T" "---"
+
+    [<Test>]
+    member public this.``Async.AsyncToolTips``() = 
+        let fileContent = """let a = 
+                             async {
+                                 let ms = new System.IO.MemoryStream(Array.create 1000 1uy)
+                                 let toFill = Array.create 2000 0uy
+                                 let! x = ms.AsyncRead(2000)
+                                 return x
+                             }"""
+        this.AssertQuickInfoContainsAtEndOfMarker(fileContent,"asy","AsyncBuilder")
+        this.VerifyQuickInfoDoesNotContainAnyAtEndOfMarker fileContent "asy" "---"
+
+    [<Test>]
+    member public this.``Regression.Exceptions.Bug3723``() = 
+        let fileContent = """exception E3E of int * int
+                             exception E4E of (int * int)
+                             exception E5E = E4E"""
+        // E3E should be un-parenthesized
+        this.VerifyQuickInfoDoesNotContainAnyAtEndOfMarker fileContent "exception E3" "(int * int)"
+        // E4E should be parenthesized
+        this.AssertQuickInfoContainsAtEndOfMarker(fileContent,"exception E4","(int * int)")
+        // E5E is an alias - should contain name of the aliased exception
+        this.AssertQuickInfoContainsAtEndOfMarker(fileContent,"exception E5","E4E")
+
+    [<Test>]
+    member public this.``Regression.Classes.Bug4066``() = 
+        let fileContent = """type Foo() as this =
+                                 do this |> ignore
+                                 member this.Bar() = this"""
+        this.AssertQuickInfoContainsAtEndOfMarker(fileContent,"type Foo() as thi","this")
+        this.VerifyQuickInfoDoesNotContainAnyAtEndOfMarker fileContent "type Foo() as thi" "ref"
+
+        this.AssertQuickInfoContainsAtEndOfMarker(fileContent,"do thi","this")
+        this.VerifyQuickInfoDoesNotContainAnyAtEndOfMarker fileContent "do thi" "ref"
+
+        this.AssertQuickInfoContainsAtEndOfMarker(fileContent,"member thi","this")
+        this.VerifyQuickInfoDoesNotContainAnyAtEndOfMarker fileContent "member thi" "ref"
+
+        this.AssertQuickInfoContainsAtEndOfMarker(fileContent,"Bar() = thi","this")
+        this.VerifyQuickInfoDoesNotContainAnyAtEndOfMarker fileContent "Bar() = thi" "ref"
+
+    [<Test>]
+    member public this.``Regression.Classes.Bug2362``() = 
+        let fileContent = """let append mm nn = fun ac -> mm (nn ac)"""
+        this.AssertQuickInfoContainsAtEndOfMarker(fileContent,"let appen","mm:('a -> 'b) -> nn:('c -> 'a) -> ac:'c -> 'b")
+        // check consistency of QuickInfo for 'm' and 'n', which is the main point of this test
+        this.AssertQuickInfoContainsAtEndOfMarker(fileContent,"let append m","'a -> 'b")
+        this.AssertQuickInfoContainsAtEndOfMarker(fileContent,"let append mm n","'c -> 'a")
+
+    [<Test>]
+    member public this.``Regression.ModuleAlias.Bug3790a``() = 
+        let fileContent = """module ``Some`` = Microsoft.FSharp.Collections.List
+                             module None = Microsoft.FSharp.Collections.List"""
+        this.VerifyQuickInfoDoesNotContainAnyAtEndOfMarker fileContent "module ``So" "Option"
+        this.VerifyQuickInfoDoesNotContainAnyAtEndOfMarker fileContent "module No" "Option"
+
+    [<Test>]
+    member public this.``Regression.ModuleAlias.Bug3790b``() = 
+        let code =
+                                    [ "#light"
+                                      "module ``Some`` = Microsoft.FSharp.Collections.List"
+                                      "let _ = ``Some``.append [] []" ]
+        let (_, _, file) = this.CreateSingleFileProject(code)
+        
+        // Test quickinfo in place where the declaration is used
+        MoveCursorToEndOfMarker(file, "= ``So")
+        let tooltip = GetQuickInfoAtCursor file
+        AssertNotContains(tooltip, "Option")
+            
+    [<Test>]
+    member public this.``Regression.ActivePatterns.Bug4100a``() = 
+        let fileContent = """let (|Lazy|) x = x
+                             match 0 with | Lazy y -> ()"""
+        // Test quickinfo in place where the declaration is used
+        this.VerifyQuickInfoDoesNotContainAnyAtEndOfMarker fileContent "with | Laz" "'?"    // e.g. "Lazy: '?3107 -> '?3107", "Lazy: 'a -> 'a" will be fine
+
+    [<Test>]
+    member public this.``Regression.ActivePatterns.Bug4100b``() = 
+        let fileContent = """let Some (a:int) = a
+                             match None with
+                             | Some _ -> ()
+                             | _ -> ()
+                                      
+                             let (|NSome|) (a:int) = a
+                             let NSome (a:int) = a.ToString()
+                             match 0 with 
+                             | NSome _ -> ()"""
+        // This shouldn't be the local function - it should find the 'Some' union case
+        this.VerifyQuickInfoDoesNotContainAnyAtEndOfMarker fileContent "| Som" "int -> int"
+        // This shouldn't find the function returning string but a pattern returning int
+        this.VerifyQuickInfoDoesNotContainAnyAtEndOfMarker fileContent "| NSom" "int -> string"
+
+    [<Test>]
+    member public this.``Regression.ActivePatterns.Bug4103``() = 
+        let fileContent = """let (|Lazy|) x = x
+                             match 0 with | Lazy y -> ()"""
+        // Test quickinfo in place where the declaration is used
+        this.VerifyQuickInfoDoesNotContainAnyAtEndOfMarker fileContent "(|Laz" "Control.Lazy"
+        this.AssertQuickInfoContainsAtEndOfMarker(fileContent,"(|Laz","|Lazy|")
+            
+    // This test checks that we don't show any tooltips for operators
+    // (which is currently not supported, but it used to collide with support for active patterns)
+    [<Test>]
+    member public this.``Regression.NoTooltipForOperators.Bug4567``() = 
+        let fileContent = """let ( |+| ) a b = a + b
+                             let n = 1 |+| 2
+                             let b = true || false
+                             ()"""
+        this.AssertQuickInfoContainsAtEndOfMarker(fileContent,"( |+","")
+        this.AssertQuickInfoContainsAtEndOfMarker(fileContent,"1 |+","")
+        this.AssertQuickInfoContainsAtEndOfMarker(fileContent,"true |","")
+
+    // Check to see that two distinct projects can be present
+    [<Test>]
+    member public this.``AcrossTwoProjects``() =
+        use _guard = this.UsingNewVS()
+        let solution = this.CreateSolution()
+        let project1 = CreateProject(solution,"testproject1")
+        let file1 = AddFileFromText(project1,"File1.fs",
+                                    ["#light"
+                                     "type (*bob*)Bob1() = "
+                                     "    let x = 1"])
+        let file1 = OpenFile(project1,"File1.fs")
+        let project2 = CreateProject(solution,"testproject2")
+        let file2 = AddFileFromText(project2,"File2.fs",
+                                    ["#light"
+                                     "type (*bob*)Bob2() = "
+                                     "    let x = 1"])
+        let file2 = OpenFile(project2,"File2.fs")
+        
+        // Check Bob1
+        MoveCursorToEndOfMarker(file1,"type (*bob*)Bob")
+        let tooltip = time1 GetQuickInfoAtCursor file1 "Time of file1 tooltip"
+        printf "Tooltip for file1:\n%s\n" tooltip
+        Assert.IsTrue(tooltip.Contains("Bob1 ="))
+        
+        // Check Bob2
+        MoveCursorToEndOfMarker(file2,"type (*bob*)Bob")
+        let tooltip = time1 GetQuickInfoAtCursor file2 "Time of file2 tooltip"
+        printf "Tooltip for file2:\n%s\n" tooltip
+        Assert.IsTrue(tooltip.Contains("Bob2 ="))
+        
+    // In this bug, relative paths with .. in them weren't working.
+    [<Test>]
+    [<Category("PerfCheck")>]
+    member public this.``BugInRelativePaths``() =
+        use _guard = this.UsingNewVS()
+        let solution = this.CreateSolution()
+        let project = CreateProject(solution,"testproject")
+        let file1 = AddFileFromText(project,"File1.fs",
+                                    ["#light"
+                                     "type Bob() = "
+                                     "    let x = 1"])
+        let file2 = AddFileFromText(project,"..\\File2.fs",
+                                    ["#light"
+                                     "let bob = new File1.Bob()"])
+        let file1 = OpenFile(project,"File1.fs")
+        let file2 = OpenFile(project,"..\\File2.fs")
+        
+        // Get the tooltip at type Bob     
+        MoveCursorToEndOfMarker(file2,"let bo")
+        let tooltip = time1 GetQuickInfoAtCursor file2 "Time of first tooltip"
+        printf "First-%s\n" tooltip
+        AssertContains(tooltip,"File1.Bob")
+        
+        // Get the tooltip again
+        MoveCursorToEndOfMarker(file2,"let bo")
+        let tooltip = time1 GetQuickInfoAtCursor file2 "Time of second tooltip"
+        printf "Second-%s\n" tooltip
+        AssertContains(tooltip,"File1.Bob")
+
+    // QuickInfo over a type that references types in an unreferenced assembly works.        
+    [<Test>]
+    [<Category("PerfCheck")>]
+    member public this.``MissingDependencyReferences.QuickInfo.Bug5409``() =     
+        let code = 
+                                    ["#light"
+                                     "let myForm = new System.Windows.Forms.Form()"
+                                    ]
+        let (_, _, file) = this.CreateSingleFileProject(code, references = ["System.Windows.Forms"])
+        MoveCursorToEndOfMarker(file,"myFo")
+        let tooltip = time1 GetQuickInfoAtCursor file "Time of first tooltip"
+        printf "First-%s\n" tooltip
+//        ShowErrors(project)
+        AssertContains(tooltip,"Form")
+
+    /// In this bug, the EOF token was reached before the parser could close the (, with, and let
+    /// The fix--at the point in time it was fixed--was to modify the parser to send a limitted number
+    /// of additional EOF tokens to allow the recovery code to proceed up the change of productions
+    /// in the grammar.
+    [<Test>]
+    member public this.``Regression.Bug1605``() = 
+        let fileContent = """let rec f l =
+                                 match l with
+                                 | [] -> string.Format(
+                                 | x::xs -> "hello" """
+        // This string doesn't matter except that it should prove there is some datatip present.
+        this.AssertQuickInfoContainsAtEndOfMarker(fileContent,"| [] -> str","string")
+        
+    [<Test>]
+    member public this.``Regression.Bug4642``() =   
+        let fileContent = """ "AA".Chars """
+        this.AssertQuickInfoContainsAtEndOfMarker(fileContent,"\"AA\".Ch","int -> char")
+
+    /// Complete a member completion and confirm that its data tip contains the fragments
+    /// in rhsContainsOrder
+    member public this.AssertMemberDataTipContainsInOrder(code : list<string>,marker,completionName,rhsContainsOrder) =
+        let code = code |> Seq.collect (fun s -> s.Split [|'\r'; '\n'|]) |> List.ofSeq
+        let (_, project, file) = this.CreateSingleFileProject(code, fileKind = SourceFileKind.FSX)
+        TakeCoffeeBreak(this.VS) (* why needed? *)       
+        MoveCursorToEndOfMarker(file,marker)
+        let completions = CtrlSpaceCompleteAtCursor file
+        match completions |> Array.tryFind (fun (name, _, _, _) -> name = completionName) with
+        | Some(_, _, descrFunc, _) ->
+            let descr = descrFunc()
+            AssertContainsInOrder(descr,rhsContainsOrder)
+        | None -> 
+            Console.WriteLine("Could not find completion name '{0}'", completionName)
+            ShowErrors(project)
+            Assert.Fail()
+
+    [<Test>]
+    //``CompletiongListItem.DocCommentsOnMembers`` and with //Regression 5856
+    member public this.``Regression.MemberDefinition.DocComments.Bug5856_1``() =
+        this.AssertMemberDataTipContainsInOrder
+            ((*code *)
+              [
+               "type MyType = "
+               "    /// Hello"
+               "    static member Overload() = 0"
+               "    /// Hello2"
+               "    static member Overload(x:int) = 0"
+               "    /// Hello3"
+               "    static member NonOverload() = 0"
+               "MyType."
+               ] ,
+             (* marker *)
+             "MyType.",
+             (* completed item *)             
+             "Overload", 
+             (* expect to see in order... *)
+             [
+              "static member MyType.Overload : unit -> int";
+              "static member MyType.Overload : x:int -> int";
+              "Hello"
+             ]
+            )
+
+    [<Test>]
+    member public this.``Regression.MemberDefinition.DocComments.Bug5856_2``() =
+        this.AssertMemberDataTipContainsInOrder
+            ((*code *)
+              [
+               "module Outer ="
+               "    /// Comment"
+               "    module Inner ="
+               "        let x = 1"
+               "let x() = "
+               "    Outer."
+               ] ,
+             (* marker *)
+             "Outer.",
+             (* completed item *)             
+             "Inner", 
+             (* expect to see in order... *)
+             [
+              "module Inner";
+              "from"; "Outer";
+              "Comment"
+             ]
+            )
+
+    [<Test>]
+    member public this.``Regression.MemberDefinition.DocComments.Bug5856_3``() =
+        this.AssertMemberDataTipContainsInOrder
+            ((*code *)
+              [
+               "module Module ="
+               "    /// Union comment"
+               "    type Union ="
+               "        /// Case comment"
+               "        | Case of int"
+               "let x() = "
+               "    Module."
+               ] ,
+             (* marker *)
+             "Module.",
+             (* completed item *)             
+             "Case", 
+             (* expect to see in order... *)
+             [
+              "union case Module.Union.Case: int -> Module.Union";
+              "Case comment";
+             ]
+            )
+
+    [<Test>]
+    member public this.``Regression.MemberDefinition.DocComments.Bug5856_4``() =
+        this.AssertMemberDataTipContainsInOrder
+            ((*code *)
+              [
+               "module Module ="
+               "    /// Union comment"
+               "    type Union ="
+               "        /// Case comment"
+               "        | Case of int"
+               "let x() = "
+               "    Module."
+               ] ,
+             (* marker *)
+             "Module.",
+             (* completed item *)             
+             "Union", 
+             (* expect to see in order... *)
+             [
+              "type Union = | Case of int";
+              //"Full name:"; "Module.Union";
+              "Union comment";
+             ]
+            )
+
+    [<Test>]
+    member public this.``Regression.MemberDefinition.DocComments.Bug5856_5``() =
+        this.AssertMemberDataTipContainsInOrder
+            ((*code *)
+              [
+               "module Module ="
+               "    /// Pattern comment"
+               "    let (|Pattern|) = 0"
+               "let x() = "
+               "    Module."
+               ] ,
+             (* marker *)
+             "Module.",
+             (* completed item *)             
+             "Pattern", 
+             (* expect to see in order... *)
+             [
+              "active recognizer Pattern: int";
+              //"Full name:"; "Module";  "|Pattern|";
+              "Pattern comment";
+             ]
+            )
+
+    [<Test>]
+    member public this.``Regression.MemberDefinition.DocComments.Bug5856_6``() =
+        this.AssertMemberDataTipContainsInOrder
+            ((*code *)
+              [
+               "module Module ="
+               "    /// A comment"
+               "    exception MyException of int"
+               "let x() = "
+               "    Module."
+               ] ,
+             (* marker *)
+             "Module.",
+             (* completed item *)             
+             "MyException", 
+             (* expect to see in order... *)
+             [
+              "exception MyException of int";
+              //"Full name:"; "Module";  "MyException";
+              "A comment";
+             ]
+            )
+
+    [<Test>]
+    member public this.``Regression.MemberDefinition.DocComments.Bug5856_7``() =
+        this.AssertMemberDataTipContainsInOrder
+            ((*code *)
+              [
+               "type Record = {"
+               "    /// A comment"
+               "    field : int"
+               "    }"
+               "let record = {field = 1}"
+               "let x() ="
+               "    record."
+               ] ,
+             (* marker *)
+             "record.",
+             (* completed item *)             
+             "field", 
+             (* expect to see in order... *)
+             [
+              "Record.field: int";
+              "A comment";
+             ]
+            )
+
+    [<Test>]
+    member public this.``Regression.MemberDefinition.DocComments.Bug5856_8``() =
+        this.AssertMemberDataTipContainsInOrder
+            ((*code *)
+              [
+               "type Foo ="
+               "    /// A comment"
+               "    static member Property"
+               "        with get() = \"\""
+               "let x() = "
+               "    Foo."
+               ] ,
+             (* marker *)
+             "Foo.",
+             (* completed item *)             
+             "Property", 
+             (* expect to see in order... *)
+             [
+              "property Foo.Property: string";
+              "A comment";
+             ]
+            )
+
+    [<Test>]
+    member public this.``Regression.MemberDefinition.DocComments.Bug5856_9``() =
+        this.AssertMemberDataTipContainsInOrder
+            ((*code *)
+              [
+               "module Module ="
+               "    /// A comment"
+               "    type Class = class end"
+               "let x() = "
+               "    Module."
+               ] ,
+             (* marker *)
+             "Module.",
+             (* completed item *)             
+             "Class", 
+             (* expect to see in order... *)
+             [
+              "type Class";
+              //"Full name:"; "Module";  "Class";
+              "A comment";
+             ]
+            )
+
+    [<Test>]
+    member public this.``Regression.MemberDefinition.DocComments.Bug5856_10``() =
+        this.AssertMemberDataTipContainsInOrder
+            ((*code *)
+              [
+               "System.String."
+               ] ,
+             (* marker *)
+             "String.",
+             (* completed item *)             
+             "Format", 
+             (* expect to see in order... *)
+             [
+              "System.String.Format(";
+              "[Filename:"; "mscorlib.dll]";
+              "[Signature:M:System.String.Format(System.String,System.Object[])]";
+             ]
+            )
+ 
+    [<Test>]
+    member public this.``Regression.MemberDefinition.DocComments.Bug5856_12``() =
+        this.AssertMemberDataTipContainsInOrder
+            ((*code *)
+              [
+               "System."
+               ] ,
+             (* marker *)
+             "System.",
+             (* completed item *)             
+             "Action", 
+             (* expect to see in order... *)
+             [
+              "type Action";
+              "  delegate of"
+              "[Filename:"; "mscorlib.dll]";
+              "[Signature:T:System.Action]"
+              "type Action<";
+              "  delegate of"
+              "[Filename:"; "mscorlib.dll]";
+              "[Signature:T:System.Action`1]"
+              "type Action<";
+              "  delegate of"
+              "[Filename:"; "mscorlib.dll]";
+              "[Signature:T:System.Action`2]"
+             ]
+            )    
+
+    [<Test>]
+    member public this.``Regression.MemberDefinition.DocComments.Bug5856_13``() =
+        this.AssertMemberDataTipContainsInOrder
+            ((*code *)
+              [
+               "System.Collections.Generic.Dictionary."
+               ] ,
+             (* marker *)
+             "Dictionary.",
+             (* completed item *)             
+             "KeyCollection", 
+             (* expect to see in order... *)
+             [
+              "type KeyCollection<";
+              "member CopyTo"; 
+              "[Filename:"; "mscorlib.dll]";
+              "[Signature:T:System.Collections.Generic.Dictionary`2.KeyCollection]"
+             ]
+            )   
+
+    [<Test>]
+    member public this.``Regression.MemberDefinition.DocComments.Bug5856_14``() =
+        this.AssertMemberDataTipContainsInOrder
+            ((*code *)
+              [
+               "System."
+               ] ,
+             (* marker *)
+             "System.",
+             (* completed item *)             
+             "ArgumentException", 
+             (* expect to see in order... *)
+             [
+              "type ArgumentException";
+              "member Message"; 
+              "[Filename"; "mscorlib.dll]";
+              "[Signature:T:System.ArgumentException]"
+             ]
+            )    
+
+    [<Test>]
+    member public this.``Regression.MemberDefinition.DocComments.Bug5856_15``() =
+        this.AssertMemberDataTipContainsInOrder
+            ((*code *)
+              [
+               "System.AppDomain."
+               ] ,
+             (* marker *)
+             "AppDomain.",
+             (* completed item *)             
+             "CurrentDomain", 
+             (* expect to see in order... *)
+             [
+              "property System.AppDomain.CurrentDomain: System.AppDomain";
+              "[Filename"; "mscorlib.dll]";
+              "[Signature:P:System.AppDomain.CurrentDomain]"
+             ]
+            ) 
+
+
+    [<Test>]
+    member public this.``Regression.ExtensionMethods.DocComments.Bug6028``() =
+        this.AssertMemberDataTipContainsInOrder
+            ((*code *)
+              [
+               @"open System.Linq
+let rec query:System.Linq.IQueryable<_> = null
+query."
+               ] ,
+             (* marker *)
+             "query.",
+             (* completed item *)             
+             "All", 
+             (* expect to see in order... *)
+             [
+              "IQueryable.All";
+              "[Filename"; "System.Core.dll]";
+              "[Signature:M:System.Linq.Enumerable.All``1"
+             ]
+            ) 
+            
+    [<Test>]
+    member public this.``Regression.OnMscorlibMethodInScript.Bug6489``() =
+        this.AssertMemberDataTipContainsInOrder
+            ((*code *)
+              [
+               "let Func() = 
+    let actual = [| |]
+    actual."
+               ] ,
+             (* marker *)
+             "actual.",
+             (* completed item *)             
+             "CopyTo", 
+             (* expect to see in order... *)
+             [
+              "[Filename"; "Reference Assemblies\Microsoft\Framework\.NETFramework"; "mscorlib.dll]";
+              "[Signature:M:System.Array.CopyTo("
+             ]
+            ) 
+              
+              
+    /// BUG: intelisense on "self" parameter in implicit ctor classes is wrong
+    [<Test>]
+    member public this.``Regression.CompListItemInfo.Bug5694``() =
+        this.AssertMemberDataTipContainsInOrder
+            ((*code *)
+              [
+                 "type Form2() as self ="
+                 "    inherit System.Windows.Forms.Form()"
+                 "    let f() = self."
+               ] ,
+             (* marker *)
+             "self.",
+             (* completed item *)             
+             "AcceptButton", 
+             (* expect to see in order... *)
+             [
+              "[Filename:"; "System.Windows.Forms.dll]"
+              "[Signature:P:System.Windows.Forms.Form.AcceptButton]"
+             ]
+            )
+
+
+    /// Bug 4592: Check that ctors are displayed from C# classes, i.e. the "new" lines below.
+    [<Test>]
+    member public this.``Regression.Class.Printing.CSharp.Classes.Only..Bug4592``() =
+        this.AssertMemberDataTipContainsInOrder
+            ((*code *)
+              ["#light";
+              "System.Random"] ,
+             (* marker *)
+             "System.Random",
+             (* completed item *)             
+             "Random", 
+             (* expect to see in order... *)
+             ["type Random =";
+              "  new : unit -> Random + 1 overload";
+              "  member Next : unit -> int + 2 overloads";  
+              "  member NextBytes : buffer:byte[] -> unit"; (* methods sorted alpha *)
+              "  member NextDouble : unit -> float";]
+            )
+
+    [<Test>]
+    member public this.``GenericDotNetMethodShowsComment``() =
+        this.AssertMemberDataTipContainsInOrder
+            ((*code *)
+              ["System.Linq.ParallelEnumerable."
+               ] ,
+             (* marker *)
+             "ParallelEnumerable.",
+             (* completed item *)             
+             "ElementAt", 
+             (* expect to see in order... *)
+             [
+              "System.Core";
+              "Signature:M:System.Linq.ParallelEnumerable.ElementAt``1(System.Linq.ParallelQuery{``0},System.Int32"
+             ]
+            )
+
+    /// Bug 4624: Check the order in which members are printed, C# classes
+    [<Test>]
+    member public this.``Regression.Class.Printing.CSharp.Classes.Bug4624``() =
+        //let f (x:System.Security.Policy.CodeConnectAccess) = x.
+        this.AssertMemberDataTipContainsInOrder
+            ((*code *)
+              ["#light";
+               "System.Security.Policy.CodeConnectAccess"],
+             (* marker *)
+             "System.Security.Policy.CodeConnectAccess",
+             (* completed item *)             
+             "CodeConnectAccess", 
+             (* expect to see in order... *)
+             // Pre fix output is mixed up
+             [ "type CodeConnectAccess =";
+               "  new : allowScheme:string * allowPort:int -> CodeConnectAccess";
+               "  member Equals : o:obj -> bool";
+               "  member GetHashCode : unit -> int";   (* method *)
+               "  member Port : int";
+               "  member Scheme : string";
+               "  static val DefaultPort : int";       (* static val after instance, but before static method *)
+               "  static val OriginPort : int";
+               "  static val OriginScheme : string";
+               "  static val AnyScheme : string";
+               "  static member CreateAnySchemeAccess : allowPort:int -> CodeConnectAccess";
+               "  ...";
+             ])
+
+    /// Bug 4624: Check the order in which members are printed, F# classes
+    [<Test>]
+    member public this.``Regression.Class.Printing.FSharp.Classes.Bug4624``() =
+        this.AssertMemberDataTipContainsInOrder
+            ((*code *)
+              ["#light";               
+               "type F1() = ";
+               "    class        ";
+               "        inherit System.Windows.Forms.Form()";
+               "        abstract AAA : int  with get";
+               "        abstract ZZZ : int  with get";
+               "        abstract AAA : bool with set";
+               "        val x : F1";
+               "        static val x : F1";
+               "        static member A() = 12";
+               "        member this.B() = 12";
+               "        static member C() = 12";
+               "        member this.D() = 12";
+               "        member this.D with get() = 12 and set(12) = ()";
+               "        member this.D(x:int,y:int) = 12";
+               "        member this.D(x:int) = 12";
+               "        member this.D x y z = [1;x;y;z]";
+               "        override this.ToString() = \"\"";
+               "        interface System.IDisposable with";
+               "            override this.Dispose() = ()        ";
+               "        end";
+               "    end";
+               "type A1 = F1"],
+             (* marker *)
+             "type A1 = F1",
+             (* completed item *)             
+             "F1", 
+             (* expect to see in order... *)
+             // Pre fix output is mixed up
+             [ "type F1 =";
+               "  inherit Form";
+               "  interface IDisposable";
+               "  new : unit -> F1";
+               "  val x: F1";
+               "  abstract member AAA : int";
+               "  abstract member ZZZ : int";
+               "  abstract member AAA : bool with set";
+               "  member B : unit -> int";
+               "  member D : unit -> int";
+               "  member D : x:int -> int";
+               "  ...";
+               //"  member D : int";
+               //"  member D : int with set";
+               //"  static val x: F1";
+               //"  static member A : unit -> int";
+               //"  static member C : unit -> int";
+             ])
+
+(* TODO why does this portion not work?  specifically, last assert fails 
+        printfn "changing file..."
+        ReplaceFileInMemory file1 ["#light"
+                                   "let xx = \"foo\""   // now x is string
+                                   "printfn \"hi\""]
+
+        // assert p1 xx is string
+        MoveCursorToEndOfMarker(file1,"let x")
+        TakeCoffeeBreak(this.VS) 
+        let tooltip = GetQuickInfoAtCursor file1
+        AssertContains(tooltip,"string")
+
+        // assert p2 yy is int
+        MoveCursorToEndOfMarker(file2,"let y")
+        let tooltip = GetQuickInfoAtCursor file2
+        AssertContains(tooltip,"int")
+
+        AssertNoErrorsOrWarnings(project1)
+        AssertNoErrorsOrWarnings(project2)
+
+        printfn "rebuilding dependent project..."
+        // (re)build p1 (with xx now string)
+        Build(project1) |> ignore
+        TakeCoffeeBreak(this.VS) 
+
+        AssertNoErrorsOrWarnings(project1)
+        AssertNoErrorsOrWarnings(project2)
+
+        // assert p2 yy is now string
+        MoveCursorToEndOfMarker(file2,"let y")
+        let tooltip = GetQuickInfoAtCursor file2
+        AssertContains(tooltip,"string")
+*)
+
+(*------------------------------------------IDE automation starts here -------------------------------------------------*)
+    [<Test>]
+    member public this.``Automation.Regression.AccessibilityOnTypeMembers.Bug4168``() =
+        let fileContent = """module Test
+                             type internal Foo2(*Marker*) () = 
+                                  member public this.Prop1 = 12
+                                  member internal this.Prop2 = 12
+                                  member private this.Prop3 = 12
+                                  public new(x:int) = new Foo2()
+                                  internal new(x:int,y:int) = new Foo2()
+                                  private new(x:int,y:int,z:int) = new Foo2()"""
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker*)", "type internal Foo2")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker*)", "private new : x:int * y:int * z:int -> Foo2")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker*)", "new : x:int * y:int -> Foo2")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker*)", "private new")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker*)", "member Prop1")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker*)", "member Prop2")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker*)", "member private Prop3")
+
+    [<Test>]
+    member public this.``Automation.Regression.AccessorsAndMutators.Bug4276``() =
+        let fileContent = """type TestType1(*Marker1*)( x : int , y : int ) =  
+                                 let mutable x = x
+                                 let mutable y = y
+     
+                                 // Property with getter and setter
+                                 member this.X with get () = x 
+                                               and  set x' = x <- x'
+
+                                 // Property with setter only
+                                 member this.Y with set y' = y <- y'
+
+                                 // Property with getter only
+                                 member this.Length with get () = sqrt(float (x * x + y * y))
+
+                                 member this.Item with get (i : int) = match i with | 0 -> x | 1 -> y | _ -> failwith "Incorrect index"
+
+                             let point = TestType1(10,10)
+
+                             point.X <- 3
+                             point.Y <- 4
+
+                             let x = point.[0]
+                             let y = point.[1]
+
+                             let bitArray = new System.Collections.BitArray(*Marker2*)(1)
+
+                             point.Length |> ignore"""
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker1*)", "type TestType1")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker1*)", "member Length : float")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker1*)", "member Item")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker1*)", "member X : int")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker1*)", "member Y : int")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker2*)", "type BitArray")
+        //this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker2*)", "member Length : int") // trimmed quick info doesn't contain all entries
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker2*)", "member Count : int")
+        this.VerifyQuickInfoDoesNotContainAnyAtStartOfMarker fileContent "(*Marker2*)" "get_Length"
+        this.VerifyQuickInfoDoesNotContainAnyAtStartOfMarker fileContent "(*Marker2*)" "set_Length"
+
+    [<Test>]
+    [<Ignore("DocComment issue")>]
+    member public this.``Automation.AutoOpenMyNamespace``() =
+        let fileContent ="""namespace System.Numerics
+                            type t = BigInteger(*Marker1*)"""
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "r(*Marker1*)", "type BigInteger")
+
+    [<Test>]
+    member public this.``Automation.Regression.BeforeAndAfterIdentifier.Bug4371``() =
+        let fileContent = """module Test
+                             let f arg1 (arg2, arg3, arg4) arg5 = 42
+                             let goo a = f(*Marker1*) 12 a
+
+                             type printer = System.Console
+                             let z = (*Marker3*)printer.BufferWidth(*Marker2*)"""
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker1*)", "Full name: Test.f")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker1*)", "val f")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker2*)", "property System.Console.BufferWidth: int")
+        this.AssertQuickInfoContainsAtEndOfMarker(fileContent,"(*Marker3*)","Full name: Test.printer")
+
+    [<Test>]
+    member public this.``Automation.Regression.ConstrutorWithSameNameAsType.Bug2739``() =
+        let fileContent = """namespace AA
+                             module AA = 
+                                 type AA = | AA(*Marker1*) = 1
+                                           | BB = 2
+                             type BB = { BB(*Marker2*) : string; }"""
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker1*)", "AA.AA: AA")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker2*)", "BB.BB: string")
+
+    [<Test>]
+    member public this.``Automation.Regression.EventImplementation.Bug5471``() =
+        let fileContent = """namespace regressiontest
+                             open System
+                             open System.Windows
+                             open System.Windows.Input
+
+                             type CommandReference() =
+                                 inherit Freezable()
+ 
+                                 static let commandProperty =
+                                     DependencyProperty.Register(
+                                         "Command", 
+                                         typeof<ICommand>, 
+                                         typeof<CommandReference>, 
+                                         PropertyMetadata(PropertyChangedCallback(fun o e -> CommandReference.OnCommandChanged(o, e))))
+ 
+                                 let evt = Event<EventHandler, EventArgs>()
+ 
+                                 member this.Command
+                                     with get () = this.GetValue(commandProperty) :?> ICommand
+                                     and  set v  = this.SetValue(commandProperty, (v: ICommand) )
+ 
+                                 interface ICommand with
+ 
+                                     member this.CanExecute(parameter) =
+                                         if this.Command <> null then
+                                              this.Command.CanExecute(parameter)
+                                         else false
+ 
+                                     member this.Execute(parameter) =
+                                         this.Command.Execute(parameter)
+ 
+                                     [<CLIEvent>]
+                                     member x.CanExecuteChanged(*Marker*) = evt.Publish
+ 
+                                 static member OnCommandChanged(d: DependencyObject, e: DependencyPropertyChangedEventArgs) =
+                                         let commandReference = (d :?> CommandReference) :> ICommand
+                                         let oldCommand = e.OldValue :?> ICommand
+                                         let newCommand = e.NewValue :?> ICommand
+                                         if oldCommand <> null then
+                                             // Error: This expression has type IEvent<EventHandler,EventArgs> but is here used with type  EventHandler 
+                                             oldCommand.CanExecuteChanged.RemoveHandler(commandReference.CanExecuteChanged)
+                                         if newCommand <> null then 
+                                             // Error: This expression has type IEvent<EventHandler,EventArgs> but is here used with type  EventHandler 
+                                             newCommand.CanExecuteChanged.AddHandler(commandReference.CanExecuteChanged)
+  
+                                 override this.CreateInstanceCore() =
+                                     raise (NotImplementedException())"""
+        let (_, _, file) = this.CreateSingleFileProject(fileContent, references = ["PresentationCore"; "WindowsBase"])
+        MoveCursorToStartOfMarker(file, "(*Marker*)")
+        let tooltip = time1 GetQuickInfoAtCursor file "Time of first tooltip"
+        AssertContains(tooltip, "override CommandReference.CanExecuteChanged : IEvent<EventHandler,EventArgs>") 
+        AssertContains(tooltip, "regressiontest.CommandReference.CanExecuteChanged") 
+
+    [<Test>]
+    member public this.``Automation.ExtensionMethod``() =
+        let fileContent ="""namespace TestQuickinfo
+
+                            module BCLExtensions =
+                                type System.Random with
+                                    /// BCL class Extension method
+                                    member this.NextDice()  = this.Next() + 1
+                                    /// new BCL class Extension method with overload
+                                    member this.NextDice(a : bool)  = this.Next() + 1
+                                    /// existing BCL class Extension method with overload
+                                    member this.Next(a : bool)  = this.Next() + 1
+                                    /// BCL class Extension property
+                                    member this.DiceValue with get() = 6
+        
+                                type System.ConsoleKeyInfo with
+                                    /// BCL struct extension method
+                                    member this.ExtentionMethod()  =  100
+                                    /// BCL struct extension property
+                                    member this.ExtentionProperty with get() = "Foo"        
+
+                            module OwnCode =
+                                /// fs class
+                                type FSClass() =
+                                    class
+                                        /// fs class method original
+                                        member this.Method(a:string) = ""
+                                        /// fs class property original
+                                        member this.Prop with get(a:string) = ""
+                                    end
+    
+                                /// fs struct
+                                type FSStruct(x:int) =
+                                    struct
+                                    end
+                                    
+                            module OwnCodeExtensions =
+                                type OwnCode.FSClass with
+                                    /// fs class extension method
+                                    member this.ExtentionMethod()  =  100
+        
+                                    /// fs class extension property
+                                    member this.ExtentionProperty with get() = "Foo"
+                                    
+                                    /// fs class method extension overload
+                                    member this.Method(a:int)  =  ""
+                                    
+                                    /// fs class property extension overload
+                                    member this.Prop with get(a:int)  =  ""
+        
+                                type OwnCode.FSStruct with
+                                    /// fs struct extension method
+                                    member this.ExtentionMethod()  =  100
+        
+                                    /// fs struct extension property
+                                    member this.ExtentionProperty with get() = "Foo"      
+
+                            module BCLClass = 
+                                open BCLExtensions
+                                let rnd = new System.Random()
+                                rnd.DiceValue(*Marker11*) |>ignore
+                                rnd.NextDice(*Marker12*)() |>ignore
+                                rnd.NextDice(*Marker13*)(true) |>ignore
+                                rnd.Next(*Marker14*)(true) |>ignore
+                                
+    
+                            module BCLStruct = 
+                                open BCLExtensions
+                                let cki = new System.ConsoleKeyInfo()
+                                cki.ExtentionMethod(*Marker21*) |>ignore
+                                cki.ExtentionProperty(*Marker22*) |>ignore
+    
+                            module OwnClass = 
+                                open OwnCode
+                                open OwnCodeExtensions
+                                let rnd = new FSClass()
+                                rnd.ExtentionMethod(*Marker31*) |>ignore
+                                rnd.ExtentionProperty(*Marker32*) |>ignore
+                                rnd.Method(*Marker33*)("") |>ignore
+                                rnd.Method(*Marker34*)(6) |>ignore
+                                rnd.Prop(*Marker35*)("") |>ignore
+                                rnd.Prop(*Marker36*)(6) |>ignore
+    
+                            module OwnStruct = 
+                                open OwnCode
+                                open OwnCodeExtensions
+                                let cki = new FSStruct(100)
+                                cki.ExtentionMethod(*Marker41*) |>ignore
+                                cki.ExtentionProperty(*Marker42*) |>ignore"""
+                                
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker11*)", "property System.Random.DiceValue: int")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker11*)", "BCL class Extension property")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker12*)", "member System.Random.NextDice : unit -> int")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker12*)", "BCL class Extension method")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker13*)", "member System.Random.NextDice : a:bool -> int")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker13*)", "new BCL class Extension method with overload")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker14*)", "member System.Random.Next : a:bool -> int")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker14*)", "existing BCL class Extension method with overload")        
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker21*)", "member System.ConsoleKeyInfo.ExtentionMethod : unit -> int")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker21*)", "BCL struct extension method")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker22*)", "System.ConsoleKeyInfo.ExtentionProperty: string")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker22*)", "BCL struct extension property")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker31*)", "member FSClass.ExtentionMethod : unit -> int")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker31*)", "fs class extension method")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker32*)", "FSClass.ExtentionProperty: string")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker32*)", "fs class extension property")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker33*)", "member FSClass.Method : a:string -> string")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker33*)", "fs class method original")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker34*)", "member FSClass.Method : a:int -> string")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker34*)", "fs class method extension overload")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker35*)", "property FSClass.Prop: string -> string")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker35*)", "fs class property original")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker36*)", "property FSClass.Prop: int -> string")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker36*)", "fs class property extension overload")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker41*)", "member FSStruct.ExtentionMethod : unit -> int")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker41*)", "fs struct extension method")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker42*)", "FSStruct.ExtentionProperty: string")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker42*)", "fs struct extension property")
+
+    [<Test>]
+    member public this.``Automation.Regression.GenericFunction.Bug2868``() =
+        let fileContent ="""module Test
+                            // Hovering over a generic function (generic argument decorated with [<Measure>] attribute yields a bad tooltip
+                            let F (f :_ -> float<_>) = fun x -> f (x+1.0)
+                            let rec Gen<[<Measure>] 'u> (f:float<'u> -> float<'u>) = 
+                              Gen(*Marker*)(F f)"""
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker*)", "val Gen : f:(float -> float) -> 'a")
+        this.VerifyQuickInfoDoesNotContainAnyAtStartOfMarker fileContent "(*Marker*)" "Exception"
+        this.VerifyQuickInfoDoesNotContainAnyAtStartOfMarker fileContent "(*Marker*)" "thrown"
+
+    [<Test>]
+    [<Ignore("DocComment issue")>]
+    member public this.``Automation.IdentifierHaveDiffMeanings``() =
+        let fileContent ="""namespace NS
+                            module float(*Marker1_1*) =
+
+                                let GenerateTuple =  fun x ->   let tuple = (x,x.ToString(),(float(*Marker1_2*))x, ( fun y -> (y.ToString(),y+1)) )
+                                                                tuple
+
+                                let MySeq : (*Marker2_1*)seq<float(*Marker1_3*)> = 
+                                    seq(*Marker2_2*)    {
+                
+                                                           for i in 1..9 do
+                                     
+                                                                let myTuple = GenerateTuple i
+                                                                let fieldInt,fieldString,fieldFloat,_ = myTuple
+                                                                yield fieldFloat
+                                                        }
+            
+                                let MySet : (*Marker3_1*)Set<float> = 
+                                    MySeq 
+                                    |> Array.ofSeq
+                                    |> List.ofArray
+                                    |> Set(*Marker3_2*).ofList
+
+                                let int(*Marker4_1*) : int(*Marker4_2*) = 1
+
+                                type int(*Marker4_3*)() = 
+                                    member this.M = 1
+
+                                type T(*Marker5_1*)() =
+                                    [<DefaultValueAttribute>]
+                                    val mutable T : T
+
+                                let T = new T()
+                                let t = T.T.T.T(*Marker5_2*);
+    
+                                type ValType() = 
+                                    member this.Value with get(*Marker6_1*) () = 10
+                                                       and set(*Marker6_2*) x  = x + 1 |> ignore"""
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker1_1*)", "module float")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker1_2*)", "val float : 'T -> float (requires member op_Explicit)")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker1_2*)", "Full name: Microsoft.FSharp.Core.Operators.float")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker1_3*)", "type float = System.Double")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker1_3*)", "Full name: Microsoft.FSharp.Core.float")
+        this.AssertQuickInfoContainsAtEndOfMarker(fileContent,"(*Marker2_1*)","type seq<'T> = System.Collections.Generic.IEnumerable<'T>")
+        this.AssertQuickInfoContainsAtEndOfMarker(fileContent,"(*Marker2_1*)","Full name: Microsoft.FSharp.Collections.seq<_>")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker2_2*)", "val seq : seq<'T> -> seq<'T>")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker2_2*)", "Full name: Microsoft.FSharp.Core.Operators.seq")
+        this.AssertQuickInfoContainsAtEndOfMarker(fileContent,"(*Marker3_1*)","type Set<'T (requires comparison)> =")
+        this.AssertQuickInfoContainsAtEndOfMarker(fileContent,"(*Marker3_1*)","Full name: Microsoft.FSharp.Collections.Set")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker3_2*)", "module Set")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker3_2*)", "Functional programming operators related to the Set<_> type")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker4_1*)", "val int : int")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker4_1*)", "Full name: NS.float.int")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker4_2*)", "type int = int32")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker4_2*)", "Full name: Microsoft.FSharp.Core.int")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker4_3*)", "type int =")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker4_3*)", "member M : int")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker5_1*)", "type T =")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker5_1*)", "new : unit -> T")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker5_1*)", "val mutable T: T")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker5_2*)", "T.T: T")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker6_1*)", "member ValType.Value : int")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker6_2*)", "member ValType.Value : int with set")
+        this.VerifyQuickInfoDoesNotContainAnyAtStartOfMarker fileContent "(*Marker6_2*)" "Microsoft.FSharp.Core.ExtraTopLevelOperators.set"
+
+    [<Test>]
+    member public this.``Automation.Regression.ModuleIdentifier.Bug2937``() =
+        let fileContent ="""module XXX(*Marker*)
+                            type t = C3"""
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker*)", "module XXX")
+        this.VerifyQuickInfoDoesNotContainAnyAtStartOfMarker fileContent "(*Marker*)" "\n"
+
+    [<Test>]
+    member public this.``Automation.Regression.NamesArgument.Bug3818``() =
+        let fileContent ="""module m 
+                            [<System.AttributeUsage(System.AttributeTargets.All, AllowMultiple(*Marker1*) = true)>]
+                            type T = class
+                                     end"""
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker1*)", "property System.AttributeUsageAttribute.AllowMultiple: bool")
+
+    [<Test>]
+    [<Ignore("DocComment issue")>]
+    member public this.``Automation.OnUnitsOfMeasure``() =
+        let fileContent ="""namespace TestQuickinfo
+
+                            module TestCase1 =
+                                [<Measure>] 
+                                /// this type represents kilogram in UOM
+                                type kg
+                                let mass(*Marker11*) = 2.0<kg(*Marker12*)>
+
+                            module TestCase2 =
+                                [<Measure>] 
+                                /// use Set as the type name of UoM
+                                type Set
+
+                                let v1 = [1.0<Set> .. 2.0<Set> .. 5.0<Set>] |> Seq.nth 1
+
+                                (if v1 = 3.0<Set> then 0 else 1) |> ignore
+    
+                                let twoSets = 2.0<Set>
+    
+                                [1.0<Set(*Marker21*)>]
+                                |> Set.ofList
+                                |> Set(*Marker22*).isEmpty 
+                                |> ignore"""
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker11*)", "val mass : float<kg>")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker11*)", "Full name: TestQuickinfo.TestCase1.mass")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker11*)", "inherits: System.ValueType")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker12*)", "[<Measure>]")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker12*)", "type kg")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker12*)", "this type represents kilogram in UOM")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker12*)", "Full name: TestQuickinfo.TestCase1.kg")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker21*)", "[<Measure>]")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker21*)", "type Set")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker21*)", "use Set as the type name of UoM")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker21*)", "Full name: TestQuickinfo.TestCase2.Set")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker22*)", "module Set")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker22*)", "from Microsoft.FSharp.Collections")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker22*)", "Functional programming operators related to the Set<_> type.")
+
+    [<Test>]
+    member public this.``Automation.OverRiddenMembers``() =
+        let fileContent ="""namespace QuickinfoGeneric
+
+                            module FSharpOwnCode =
+                                [<AbstractClass>]
+                                type TextOutputSink() =
+                                    abstract WriteChar : char -> unit
+                                    abstract WriteString : string -> unit
+                                    default x.WriteString(s) = s |> String.iter x.WriteChar 
+
+                                type ByteOutputSink() =
+                                    inherit TextOutputSink()    
+                                    default sink.WriteChar(c) = System.Console.Write(c)
+                                    override sink.WriteString(s) = System.Console.Write(s)   
+        
+                                let sink = new ByteOutputSink()
+                                sink.WriteChar(*Marker11*)('c') 
+                                sink.WriteString(*Marker12*)("Hello World!")"""
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker11*)", "override ByteOutputSink.WriteChar : c:char -> unit")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker12*)", "override ByteOutputSink.WriteString : s:string -> unit")
+
+    [<Test>]
+    member public this.``Automation.Regression.QuotedIdentifier.Bug3790``() =
+        let fileContent ="""module Test
+                            module ``Some``(*Marker1*) = Microsoft.FSharp.Collections.List
+                            let _ = ``Some``(*Marker2*).append [] [] """
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "``(*Marker1*)", "module List")
+        this.VerifyQuickInfoDoesNotContainAnyAtStartOfMarker fileContent "``(*Marker1*)" "Option.Some"
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "``(*Marker2*)", "module List")
+        this.VerifyQuickInfoDoesNotContainAnyAtStartOfMarker fileContent "``(*Marker2*)" "Option.Some"
+
+    [<Test>]
+    [<Ignore("Can not get QuickInfo tips")>]
+    member public this.``Automation.Setter``() =
+        let fileContent ="""type T() =
+                                 member this.XX
+                                   with set ((a:int), (b:int), (c:int)) = ()
+
+                            (new T()).XX(*Marker1*) <- (1,2,3)
+                            //===================================================
+                            // More cases:
+                            //===================================================
+                            type IFoo = interface
+                                abstract foo : int -> int
+                                end    
+                            let i : IFoo = Unchecked.defaultof<IFoo>
+                            i.foo(*Marker2*) |> ignore
+                            //===================================================
+                            type Rec =  { bar:int->int->int }
+                            let r = {bar = fun x y -> x + y }
+
+                            r.bar(*Marker3*) 1 2 |>ignore
+                            //===================================================
+                            type M() = 
+                                member this.baz x y = x + y
+                            let m = new M()
+                            m.baz(*Marker3*) 1 2 |>ignore
+                            //===================================================
+                            type T2() =
+                                 member this.Foo(a,b) = ""
+                            let t = new T2()
+                            t.Foo(*Marker4*)(1,2) |>ignore
+                            //===================================================
+                            let foo (x:int) (y:int) : int = 1
+                            foo(*Marker5*) 2 3 |> ignore"""
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker1*)", "T.XX: int * int * int")
+        this.VerifyQuickInfoDoesNotContainAnyAtStartOfMarker fileContent "(*Marker1*)" "->"
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker2*)", "IFoo.foo : int -> int")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker3*)", "Rec.bar: int -> int -> int")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker4*)", "T2.Foo : a:'a * b:'b -> string")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker5*)", "val foo : int -> int -> int")
+
+    [<Test>]
+    member public this.``Automation.Regression.TupleException.Bug3723``() =
+        let fileContent ="""namespace TestQuickinfo
+                            exception E3(*Marker1*) of int * int
+                            exception E4(*Marker2*) of (int * int)
+                            exception E5(*Marker3*) = E4"""
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker1*)", "exception E3 of int * int")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker1*)", "Full name: TestQuickinfo.E3")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker2*)", "exception E4 of (int * int)")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker2*)", "Full name: TestQuickinfo.E4")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker3*)", "exception E5 = E4")
+
+    [<Test>]
+    member public this.``Automation.TypeAbbreviations``() =
+        let fileContent ="""namespace NS
+                            module TypeAbbreviation =
+    
+                                type MyInt(*Marker1_1*) = int
+    
+                                type PairOfFloat(*Marker2_1*) = float * float
+    
+    
+                                type AbAttrName(*Marker5_1*) = AbstractClassAttribute
+      
+    
+                                type IA(*Marker3_1*) = 
+                                    abstract AbstractMember : int -> int
+        
+                                [<AbAttrName(*Marker5_2*)>]
+                                type ClassIA(*Marker3_2*)() =
+                                    interface IA with
+                                        member this.AbstractMember x = x + 1
+    
+                                type GenericClass(*Marker4_1*)<'a when 'a :> IA>() = 
+                                    static member StaticMember(x:'a) = x.AbstractMember(1)
+
+
+                                let GenerateTuple =  fun ( x : MyInt) ->    
+                                                        let myInt(*Marker1_2*),float1,float2,function1 = (x,(float)x,(float)x, ( fun y -> (y.ToString(),y+1)) )
+                                                        myInt,((float1,float2):PairOfFloat),function1
+
+                                let MySeq(*Marker2_2*) = 
+                                    seq     {
+                
+                                               for i in 1..9 do
+                                                    let myInt,pairofFloat,function1 = GenerateTuple i
+                        
+                                                    yield pairofFloat
+                                            }
+                
+                                let genericClass(*Marker4_2*) = new GenericClass<ClassIA>()"""
+
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker1_1*)", "type MyInt = int")
+        //this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker1_1*)", "Full name: NS.TypeAbbreviation.MyInt")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker1_2*)", "val myInt : MyInt")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker2_1*)", "type PairOfFloat = float * float")
+        //this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker2_1*)", "Full name: NS.TypeAbbreviation.PairOfFloat")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker2_2*)", "val MySeq : seq<PairOfFloat>")
+        //this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker2_2*)", "Full name: NS.TypeAbbreviation.MySeq")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker3_1*)", "type IA =")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker3_1*)", "abstract member AbstractMember : int -> int")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker3_2*)", "type ClassIA =")
+        //this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker3_2*)", "Full name: NS.TypeAbbreviation.ClassIA")
+        //this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker3_2*)", "implements: IA")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker4_1*)", "type GenericClass<'a (requires 'a :> IA)> =")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker4_1*)", "static member StaticMember : x:'a -> int")
+        //this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker4_1*)", "Full name: NS.TypeAbbreviation.GenericClass<_>")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker4_2*)", "val genericClass : GenericClass<ClassIA>")
+        //this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker4_2*)", "Full name: NS.TypeAbbreviation.genericClass")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker5_1*)", "type AbAttrName = AbstractClassAttribute")
+        //this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker5_1*)", "implements: System.Runtime.InteropServices._Attribute")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker5_2*)", "type AbAttrName = AbstractClassAttribute")
+        //this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker5_2*)", "implements: System.Runtime.InteropServices._Attribute")
+
+    [<Test>]
+    member public this.``Automation.Regression.TypeInferenceSenarios.Bug2362&3538``() =
+        let fileContent ="""module Test.Module1
+
+                            open System
+                            open System.Diagnostics
+                            open System.Runtime.InteropServices
+
+                            #nowarn "9"
+
+                            let append m(*Marker1*) n(*Marker2*) = fun ac(*Marker3*) -> m (n ac)
+
+                            type Foo() as this(*Marker4*) =
+                                do this(*Marker5*) |> ignore
+                                member this.Bar() =
+                                    this(*Marker6*) |> ignore
+                                    ()
+
+                            [<StructLayout(LayoutKind.Explicit)>]
+                            type A =
+                                [<DefaultValue>]
+                                val mutable x : int
+                                new () = { }
+                                member this.Prop = this.x
+    
+                            let x = new (*Marker7*)A()"""
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker1*)", "val m : ('a -> 'b)")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker2*)", "val n : ('c -> 'a)")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker3*)", "val ac : 'c")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker4*)", "val this : Foo")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker5*)", "val this : Foo")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker6*)", "val this : Foo")
+        this.AssertQuickInfoContainsAtEndOfMarker(fileContent,"(*Marker7*)","type A =")
+        this.AssertQuickInfoContainsAtEndOfMarker(fileContent,"(*Marker7*)","val mutable x: int")
+
+    [<Test>]
+    member public this.``Automation.Regression.TypemoduleConstructorLastLine.Bug2494``() =
+        let fileContent ="""namespace NS
+                            open System
+                            //regression test for bug 2494
+
+                            type PriorityQueue(*MarkerType*)<'k,'a> =
+                              | Nil(*MarkerDataConstructor*)
+                              | Branch of 'k * 'a * PriorityQueue<'k,'a> * PriorityQueue<'k,'a>
+  
+                            module PriorityQueue(*Marker3*) =
+                              let empty = Nil
+  
+                              let minKeyValue = function
+                                | Nil             -> failwith "empty queue"
+                                | Branch(k,a,_,_) -> (k,a)
+    
+                              let minKey pq = fst (minKeyValue pq(*MarkerVal*))
+  
+                              let singleton(*MarkerLastLine*) k a = Branch(k,a,Nil,Nil)"""
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*MarkerType*)", "type PriorityQueue")
+        //this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*MarkerType*)", "Full name: NS.PriorityQueue<_,_>")
+        //this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*MarkerType*)", "implements: IComparable")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*MarkerDataConstructor*)", "union case PriorityQueue.Nil: PriorityQueue<'k,'a>")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker3*)", "module PriorityQueue")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*MarkerVal*)", "val pq : PriorityQueue<'a,'b>")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*MarkerLastLine*)", "val singleton : k:'a -> a:'b -> PriorityQueue<'a,'b>")
+
+    [<Test>]
+    member public this.``Automation.WhereQuickInfoShouldNotShowUp``() =
+        let fileContent ="""namespace Test
+
+                            module Helper = 
+                                /// Tests if passed System.Numerics.BigInteger(*Marker1*) argument is prime
+                                let IsPrime x =  
+                                    let mutable i = 2I
+                                    let mutable foundFactor = false  
+                                    while not foundFactor && i < x do
+                                        (*
+                                            the most naive way to test for number being prime
+                                            Works great for small int(*Marker2*)
+                                        *)
+                                        if x % i = 0I then  
+                                            foundFactor <- true  
+                                        i <- i + 1I 
+                                    not foundFactor
+        
+                            module App = 
+                                open Helper
+    
+                                let sumOfAllPrimesUnder1Mi =
+                                #if TEST_TWO_MI
+                                    seq(*Marker4*) { 1I .. 2000000I }
+                                #else
+                                    seq { 1I .. 1000000I(*Marker7*) }
+                                #endif
+                                    |> Seq.filter(IsPrime)
+                                    // find result after filtering seq(*Marker3*)
+                                    |> Seq.sum
+        
+                                let myString hello = "hello"(*Marker5*)
+    
+                                myString "myString"(*Marker8*)
+                                |> Seq.filter (fun c -> int c > 75)
+                                |> Seq.nth 0
+                                |> (=) 'e'(*Marker6*)
+                                |> ignore"""
+        this.VerifyQuickInfoDoesNotContainAnyAtStartOfMarker fileContent "(*Marker1*)" "BigInteger"
+        this.VerifyQuickInfoDoesNotContainAnyAtStartOfMarker fileContent "(*Marker2*)" "int"
+        this.VerifyQuickInfoDoesNotContainAnyAtStartOfMarker fileContent "(*Marker3*)" "seq"
+        this.VerifyQuickInfoDoesNotContainAnyAtStartOfMarker fileContent "(*Marker4*)" "seq"
+        this.VerifyQuickInfoDoesNotContainAnyAtStartOfMarker fileContent "(*Marker5*)" "hello"
+        this.VerifyQuickInfoDoesNotContainAnyAtStartOfMarker fileContent "(*Marker6*)" "char"
+        this.VerifyQuickInfoDoesNotContainAnyAtStartOfMarker fileContent "(*Marker7*)" "bigint"
+        this.VerifyQuickInfoDoesNotContainAnyAtStartOfMarker fileContent "(*Marker8*)" "myString"
+
+    [<Test>]
+    member public this.``Automation.Regression.XmlDocComments.Bug3157``() =
+        let fileContent ="""namespace TestQuickinfo
+                            module XmlComment =
+                                /// XmlComment J
+                                let func(*Marker*) x =
+                                    /// XmlComment K
+                                    let rec g x = 1
+                                    g x"""
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker*)", "val func : x:'a -> int")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker*)", "XmlComment J")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker*)", "Full name: TestQuickinfo.XmlComment.func")
+        this.VerifyQuickInfoDoesNotContainAnyAtStartOfMarker fileContent "(*Marker*)" "XmlComment K"
+
+    [<Test>]
+    member public this.``Automation.Regression.XmlDocCommentsOnExtensionMembers.Bug138112``() =
+        let fileContent ="""module Module1 =
+                                type T() = 
+                                    /// XmlComment M1
+                                    member this.M1() = ()
+                                type T with
+                                    /// XmlComment M2
+                                    member this.M2() = ()
+                                module public Extension =
+                                    type T with
+                                        /// XmlComment M3
+                                        member this.M3() = ()
+                            open Module1
+                            open Extension
+
+                            let x1 = T().M1(*Marker1*)()
+                            let x2 = T().M2(*Marker2*)()
+                            let x3 = T().M3(*Marker3*)()"""
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker1*)", "XmlComment M1")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker2*)", "XmlComment M2")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker3*)", "XmlComment M3")
+
+    [<Test>]
+    member public this.XmlDocCommentsForArguments() =
+        let fileContent = """
+                             type bar() =
+                                 /// <summary> Test for members</summary>
+                                 /// <param name="x1">x1 param!</param>
+                                 member this.foo (x1:int)=
+                                     System.Console.WriteLine(x1.ToString())
+                             
+                             type Uni1 = 
+                                /// <summary> Test for unions </summary>
+                                /// <param name="str">str of case1</param>
+                                | Case1 of str: string
+                                | None
+
+                             /// <summary> Test for exception types</summary>
+                             /// <param name="value">value param</param>
+                             exception Ex1 of value: string
+
+                             // Methods
+                             let f1 = (new bar()).foo(x1(*Marker1*) = 10)
+                             let f2 = System.String.Concat(1, arg1(*Marker2*) = "") 
+                             
+                             //Unions
+                             let f3 = Case1(str(*Marker3*) = "10")
+                             match f3 with 
+                             | Case1(str(*Marker4*) = "10") -> ()
+                             | _ -> ()
+                             
+                             //Exceptions
+                             let f4 = Ex1(value(*Marker5*) = "")
+                             try
+                               ()
+                             with
+                               Ex1(value(*Marker6*) = v) -> ()
+
+                             //Static parameters of type providers
+                             let provType = N1.T<Param1(*Marker7*)="hello", ParamIgnored(*Marker8*)=10>
+                             """
+
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker1*)", "x1 param!")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker2*)", "[ParamName: arg1]")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker3*)", "str of case1")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker4*)", "str of case1")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker5*)", "value param")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker6*)", "value param")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker7*)", "Param1 of string",
+                                                     addtlRefAssy = [System.IO.Path.Combine(System.Environment.CurrentDirectory,@"UnitTestsResources\MockTypeProviders\DummyProviderForLanguageServiceTesting.dll")])
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Marker8*)", "Ignored",
+                                                     addtlRefAssy = [System.IO.Path.Combine(System.Environment.CurrentDirectory,@"UnitTestsResources\MockTypeProviders\DummyProviderForLanguageServiceTesting.dll")])
+
+    member private this.VerifyUsingFsTestLib fileContent queries crossProject =
+        use _guard = this.UsingNewVS()
+        let solution = this.CreateSolution()
+        let project = CreateProject(solution,"testproject")
+        let testLibCode ="""namespace FSTestLib
+
+                            /// DocComment: This is MyStruct type, represents a struct.
+                            type MyPoint =
+                                struct
+                                    val mutable private m_X : float
+                                    val mutable private m_Y : float
+        
+                                    new (x, y) = { m_X = x; m_Y = y }
+        
+                                    /// Gets and sets X
+                                    member this.X with get () = this.m_X and set x = this.m_X <- x
+        
+                                    /// Gets and sets Y
+                                    member this.Y with get () = this.m_Y and set y = this.m_Y <- y
+        
+                                    // Length of given Point
+                                    member this.Len = sqrt ( this.X * this.X + this.Y * this.Y )
+        
+                                    static member (+) (p1 : MyPoint, p2 : MyPoint) = MyPoint(p1.X + p2.X, p1.Y + p2.Y)
+        
+                                end
+
+                            [<NoComparison;NoEquality>]
+                            /// DocComment: This is my record type.
+                            type MyEmployee = 
+                                { mutable Name  : string;
+                                  mutable Age   : int;
+                                  /// DocComment: Indicates whether the employee is full time or not
+                                  mutable IsFTE : bool }
+    
+                                interface System.IComparable with
+                                    member this.CompareTo (emp : obj) = 
+                                        let r = emp :?> MyEmployee
+                                        match r.IsFTE && this.IsFTE with
+                                        | true -> this.Age - r.Age
+                                        | _ -> System.Convert.ToInt32(this.IsFTE) - System.Convert.ToInt32(r.IsFTE)
+    
+                                override this.ToString() = sprintf "%s is %d." this.Name this.Age
+    
+                                /// DocComment: Method
+                                static member MakeDummy () =
+                                    { Name = System.String.Empty; Age = -1; IsFTE = false }
+    
+                                // TODO: Normally there's no DotCompletion after "this" here
+                                override this.Equals(ob : obj) = 
+                                    let r = ob :?> MyEmployee
+                                    this.Name = r.Name && this.Age = r.Age && this.IsFTE = r.IsFTE
+
+                            /// DocComment: This is my interface type
+                            type IMyInterface = 
+                                interface
+                                    /// DocComment: abstract method in Interface
+                                    abstract Represent : unit -> string        
+                                end
+
+                            // TODO: add formatable ToString()
+                            /// DocComment: This is my discriminated union type
+                            type MyDistance =
+                                | Kilometers of float
+                                | Miles of float
+                                | NauticalMiles of float
+    
+    
+                                /// DocComment: Static Method
+                                static member toMiles x =
+                                    Miles(
+                                        match x with
+                                        | Miles x -> x
+                                        | Kilometers x -> x / 1.6
+                                        | NauticalMiles x -> x * 1.15
+                                    )
+
+                                /// DocComment: Property        
+                                member this.toNautical =
+                                    NauticalMiles(
+                                        match this with
+                                        | Kilometers x -> x / 1.852
+                                        | Miles x -> x / 1.15
+                                        | NauticalMiles x -> x
+                                    )
+
+                                /// DocComment: Method        
+                                member this.IncreaseBy dist = 
+                                    match this with
+                                    | Kilometers x -> Kilometers (x + dist)
+                                    | Miles x -> Miles (x + dist)
+                                    | NauticalMiles x -> NauticalMiles (x + dist)
+        
+                                /// DocComment: Event
+                                static member Event = 
+                                    let evnt = new Event<string>()
+                                    evnt
+        
+                            /// DocComment: This is my enum type
+                            type MyColors =
+                                | /// DocComment: Field
+                                  Red = 0
+                                | Green = 1
+                                | Blue = 2
+    
+                            /// DocComment: This is my class type
+                            type MyCar( number: int, color:MyColors) =
+                                /// DocComment: This is static field
+                                static member Owner     = "MySelf"
+                                /// DocComment: This is instance field
+                                member this.Number      = number
+                                member this.Color       = color
+                                /// DocComment: This is static method
+                                static member Run (number:int)      = printf "%s" (number.ToString()+"Running")
+                                /// DocComment: This is instance method
+                                member this.Repair  (expense:int)  = printf "%s" ("Spent " + expense.ToString() + " for repairing. ")
+    
+                            /// DocComment: This is my delegate type
+                            type ControlEventHandler = delegate of int -> unit"""
+        let file2 =
+            if (crossProject = true) then
+                let file1 = AddFileFromTextBlob(project,"File1.fs",testLibCode)
+                let project2 = CreateProject(solution,"codeProject")
+                let file2 = AddFileFromTextBlob(project2,"File2.fs",fileContent)
+                Build(project).BuildSucceeded |> ignore
+                AddProjectReference(project2, project)
+                let file1 = OpenFile(project,"File1.fs")
+                let file2 = OpenFile(project2,"File2.fs")
+                file2
+            else
+                let file1 = AddFileFromTextBlob(project,"File1.fs",testLibCode)
+                let file2 = AddFileFromTextBlob(project,"File2.fs",fileContent)
+                let file1 = OpenFile(project,"File1.fs")
+                let file2 = OpenFile(project,"File2.fs")
+                file2
+        //Build(project).BuildSucceeded |> printf "%b"
+        for (marker, expectedTip) in queries do
+            MoveCursorToStartOfMarker(file2, marker)
+            let tooltip = time1 GetQuickInfoAtCursor file2 "Time of first tooltip"
+            printf "First-%s\n" tooltip
+            AssertContains(tooltip, expectedTip)
+
+                
+    [<Test>]
+    member public this.``Automation.XDelegateDUStructfromOwnCode``() =
+        let fileContent ="""module Test
+
+                            open FSTestLib
+                                
+                            open System.Runtime.InteropServices
+                            let ctrlSignal = ref false
+                            [<DllImport("kernel32.dll")>]
+                            extern void SetConsoleCtrlHandler(ControlEventHandler callback,bool add)
+                            let ctrlEnventHandlerStatic     = new ControlEventHandler(MyCar.Run)
+                            let ctrlEnventHandlerInstance   = new ControlEventHandler( (new MyCar(10, MyColors.Blue)).Repair )
+
+                            let IsInstanceMethod (controlEventHandler:ControlEventHandler) =
+                                // TC 32	Identifier	Delegate	Own Code	Pattern Match
+                                match controlEventHandler(*Marker1*).Method.IsStatic  with 
+                                | true -> printf "It's not a instance method. "
+                                | false -> printf " It's a instance method. " 
+    
+                            // TC 33	Event	DiscUnion	Own Code	Quotation
+                            let a = <@ MyDistance.Event(*Marker2*) @>
+
+                            let DelegateSeq =
+                                seq {   for i in 1..10 do
+                                            let newDelegate = new ControlEventHandler(MyCar.Run)
+                                            // TC 35	Identifier	Delegate	Own Code	Comp Expression
+                                            yield newDelegate(*Marker3*) }
+                
+                            let StructFieldSeq =
+                                seq { for i in 1..10 do
+                                            let a = MyPoint((float)i,2.0)
+                                            // TC 36	Field	Struct	Own Code	Comp Expression
+                                            yield a.X(*Marker4*) }"""
+        let queries =   [("(*Marker1*)", "val controlEventHandler : ControlEventHandler");
+                         ("(*Marker2*)", "property MyDistance.Event: Event<string>");
+//                         ("(*Marker2*)", "DocComment: Event");        //Fail: due to DocComments
+                         ("(*Marker3*)", "val newDelegate : ControlEventHandler");
+                         ("(*Marker4*)", "property MyPoint.X: float");
+                         ("(*Marker4*)", "Gets and sets X")]
+        this.VerifyUsingFsTestLib fileContent queries false
+
+    [<Test>]
+    member public this.``Automation.EnumDUInterfacefromFSBrowse``() =
+        let fileContent ="""module Test
+
+                            open FSTestLib
+
+                            type MyTestType() = 
+                                [<DefaultValue>]
+                                val mutable field : int 
+
+                                interface IMyInterface with 
+                                    member this.Represent () = "Implement Interface"
+
+                            [<EntryPoint>]
+                            let Main (args : string []) = 
+                                let MyEnumFieldSeq = 
+                                    seq {
+                                        for i in 1..10 do
+                                            // TC 14	Field	Enum	F# Browse	Comp Expression
+                                            let myEnumField = MyColors.Red(*Marker1*)
+                                            yield myEnumField
+                                        }
+   
+                                let MyDUList = (fun x -> 
+                                                        match x%3 with
+                                                        //TC 15	Self	DiscUnion	F# Browse	Lambda
+                                                        | 0 -> MyDistance(*Marker2*).Kilometers
+                                                        | 1 -> MyDistance.Miles
+                                                        | _ -> MyDistance.NauticalMiles
+                                                        )
+                            
+   
+
+                                //TC 16	Method	Interface	F# Browse	Lambda
+                                let resultString        = new MyTestType()
+                                                              |> fun (x : MyTestType) -> x :> IMyInterface
+                                                              |> fun (x : IMyInterface) -> x.Represent(*Marker3*)      
+                                0"""
+        let queries = [("(*Marker1*)", "Red: MyColors = 0");
+                        ("(*Marker2*)", "type MyDistance =");
+//                        ("(*Marker2*)", "DocComment: This is my discriminated union type");       //Fail: due to DocComments
+                        ("(*Marker2*)", "Full name: FSTestLib.MyDistance");
+//                        ("(*Marker3*)", "DocComment: abstract method in Interface");              //Fail: due to DocComments
+                        ("(*Marker3*)", "abstract member IMyInterface.Represent : unit -> string")
+                        ]
+        this.VerifyUsingFsTestLib fileContent queries true
+
+    [<Test>]
+    member public this.``Automation.RecordAndInterfaceFromFSProj``() =
+        let fileContent ="""module Test
+
+                            open FSTestLib
+
+                            let construct =
+                                seq {
+                                    for i in 1..10 do
+                                        // TC23 - Testing "Record" type from "F# P2P" inside "Comp Expression"
+                                        let a = MyEmployee(*Marker1*).MakeDummy()
+                                        a.Name  <- "Emp" + i.ToString()
+                                        a.Age   <- 20 + i
+                                        a.IsFTE <- System.Convert.ToBoolean(System.Random().Next(2)) 
+            
+                                        // TC25 - Testing "Identifier" of "Record" type from "F# P2P" inside "Quotation"
+                                        let b = <@ a(*Marker2*).Name @>
+            
+                                        yield a
+                                }
+
+                            // TC27 - Testing "Field/Method" of "Record" type from "F# P2P" inside "Lambda"
+                            let fte_count = 
+                                construct
+                                |> Seq.filter (fun a -> a.IsFTE(*Marker3*))
+                                |> Seq.mapi (fun i a -> i.ToString() + a.ToString(*Marker4*)() )
+                                |> Seq.length
+
+                            // TC24 - Testing "Identifier" of "Interface" type from "F# P2P" inside "Pattern Matching"
+                            type MyTestType() = 
+                                [<DefaultValue>]
+                                val mutable x : int
+    
+                                interface IMyInterface with 
+                                    member this.Represent () = this.x.ToString()
+
+                            let res = 
+                                seq { yield MyTestType()
+                                      yield Unchecked.defaultof<MyTestType> }
+                                |> Seq.map (fun a ->
+                                                let myItf = a :> IMyInterface
+                                                match myItf with
+                                                | x when x = Unchecked.defaultof<IMyInterface> -> ""
+                                                | itf(*Marker5*)  -> itf.Represent() )
+                                |> Seq.filter (fun s -> s.Length > 0)
+                                |> Seq.length
+                                |> (=) 1"""
+        let queries =  [("(*Marker1*)", "type MyEmployee =");
+                        ("(*Marker1*)", "mutable IsFTE: bool;");
+//                        ("(*Marker1*)", "DocComment: This is my record type.");           //Fail: due to DocComments
+  //                      ("(*Marker1*)", "Full name: FSTestLib.MyEmployee");    // removed from declaration infos
+    //                    ("(*Marker1*)", "implements: System.IComparable");     // removed from declaration infos
+                        ("(*Marker2*)", "val a : MyEmployee");
+//                        ("(*Marker2*)", "implements: System.IComparable");     // removed from declaration infos
+                        ("(*Marker3*)", "MyEmployee.IsFTE: bool");
+//                        ("(*Marker3*)", "Indicates whether the employee is full time or not");            //Fail: due to DocComments
+                        ("(*Marker5*)", "val itf : IMyInterface")
+                        ]
+        this.VerifyUsingFsTestLib fileContent queries true
+
+    [<Test>]
+    member public this.``Automation.StructDelegateDUfromOwnCode``() =
+        let fileContent ="""module Test
+
+                            open FSTestLib
+                                
+                            open System.Runtime.InteropServices
+                            let ctrlSignal = ref false
+                            [<DllImport("kernel32.dll")>]
+                            extern void SetConsoleCtrlHandler(ControlEventHandler callback,bool add)
+                            let ctrlEnventHandlerStatic     = new ControlEventHandler(MyCar.Run)
+                            let ctrlEnventHandlerInstance   = new ControlEventHandler( (new MyCar(10, MyColors.Blue)).Repair )
+
+                            let IsInstanceMethod (controlEventHandler:ControlEventHandler) =
+                                // TC 32	Identifier	Delegate	Own Code	Pattern Match
+                                match controlEventHandler(*Marker1*).Method.IsStatic  with 
+                                | true -> printf "It's not a instance method. "
+                                | false -> printf " It's a instance method. " 
+    
+                            // TC 33	Event	DiscUnion	Own Code	Quotation
+                            let a = <@ MyDistance.Event(*Marker2*) @>
+
+
+                            let DelegateSeq =
+                                seq {   for i in 1..10 do
+                                            let newDelegate = new ControlEventHandler(MyCar.Run)
+                                            // TC 35	Identifier	Delegate	Own Code	Comp Expression
+                                            yield newDelegate(*Marker3*) }
+
+                            let StructFieldSeq =
+                                seq { for i in 1..10 do
+                                            let a = MyPoint((float)i,2.0)
+                                            // TC 36	Field	Struct	Own Code	Comp Expression
+                                            yield a.X(*Marker4*) }"""
+        let queries =  [("(*Marker1*)", "val controlEventHandler : ControlEventHandler");
+                        ("(*Marker2*)", "property MyDistance.Event: Event<string>");
+//                        ("(*Marker2*)", "DocComment: Event");     //Fail: due to DocComments
+                        ("(*Marker3*)", "val newDelegate : ControlEventHandler");
+                        ("(*Marker4*)", "property MyPoint.X: float");
+                        ("(*Marker4*)", "Gets and sets X");
+                        ]
+        this.VerifyUsingFsTestLib fileContent queries false
+
+    [<Test>]
+    member public this.``Automation.TupleRecordClassfromOwnCode``() =
+        let fileContent ="""module Test
+
+                            open FSTestLib
+
+                            let AbsTuple =  fun x ->        let tuple1 = (x,x.ToString(),(float)x, ( fun y -> (y.ToString(),y+1)) )
+                                                            let tuple2 = (-x,(-x).ToString(),(float)(-x), ( fun y -> (y.ToString(),y+1)) )
+                                                            if x >= 0 then 
+                                                            // TC 29	Self	Tuple	Own Code	Imperative
+                                                                tuple1(*Marker1*)
+                                                            else
+                                                                tuple2
+                                
+                            let GenerateMyEmployee name age = 
+                                let a = MyEmployee.MakeDummy()
+                                a.Name  <- name
+                                a.Age   <- age
+                                a.IsFTE <- System.Convert.ToBoolean(System.Random().Next(2))
+                                match a.IsFTE with
+                                | true -> a
+                                // TC 30  Operator	Record	Own Code	Pattern Match
+                                | _ -> MyEmployee(*Marker2*).MakeDummy()
+    
+                            // TC 31	Self	Class	Own Code	Quotation
+                            let myCarQuot = <@ new MyCar(*Marker3*)(19,MyColors.Red) @>
+
+                            open System.Runtime.InteropServices
+                            let ctrlSignal = ref false
+                            [<DllImport("kernel32.dll")>]
+                            extern void SetConsoleCtrlHandler(ControlEventHandler callback,bool add)
+                            let ctrlEnventHandlerStatic     = new ControlEventHandler(MyCar.Run)
+                            let ctrlEnventHandlerInstance   = new ControlEventHandler( (new MyCar(10, MyColors.Blue)).Repair )
+    
+                            let MaxTuple x y =
+                                let tuplex = (x,x.ToString() )
+                                let tupley = (y,(y).ToString())
+                                match x>y with
+                                // TC 34	Operator	Tuple	Own Code	Pattern Match
+                                | true -> tuplex(*Marker4*)
+                                | false -> tupley"""
+        let queries =  [("(*Marker1*)", "val tuple1 : int * string * float * (int -> string * int)");
+                        ("(*Marker2*)", "type MyEmployee");
+//                        ("(*Marker2*)", "DocComment: This is my record type.");       //Fail: due to DocComments
+                        ("(*Marker2*)", "Full name: FSTestLib.MyEmployee");
+                        ("(*Marker3*)", "type MyCar");
+//                        ("(*Marker3*)", "DocComment: This is my class type");         //Fail: due to DocComments
+                        ("(*Marker3*)", "Full name: FSTestLib.MyCar");
+                        ("(*Marker4*)", "val tuplex : 'a * string")
+                        ]
+        this.VerifyUsingFsTestLib fileContent queries false
+
+    [<Test>]
+    member public this.``Automation.TupleRecordfromFSBrowse``() =
+        let fileContent ="""module Test
+
+                            open FSTestLib
+
+                            let GenerateTuple =  fun x ->   let tuple = (x,x.ToString(),(float)x, ( fun y -> (y.ToString(),y+1)) ) 
+                                                            // TC 19	Identifier	Tuple	F# Browse	Lambda
+                                                            tuple(*Marker3*)
+                            let MyTupleSeq = 
+                                seq {
+                                       for i in 1..9 do
+                                            // TC 17	Identifier	Tuple	F# Browse	Comp Expression
+                                            let myTuple(*Marker1*) = GenerateTuple i
+                                            yield myTuple
+                                    }
+
+                            let GetTupleMethod tuple=
+                                let (intInTuple,stringInTuple,floatInTuple,methodInTuple) = tuple
+                                methodInTuple
+    
+                            // TC 20	method	Tuple	F# Browse	Quotation
+                            let methodSeq(*Marker4*) = Seq.map GetTupleMethod MyTupleSeq
+        
+                            let RecordArray =
+                                [| for x in 1..5
+                                        // TC 18	Method	Record	F# Browse	Imperative
+                                        ->  MyEmployee.MakeDummy(*Marker2*)()|]"""
+        let queries =  [("(*Marker1*)", "val myTuple : int * string * float * (int -> string * int)");
+                        ("(*Marker2*)", "static member MyEmployee.MakeDummy : unit -> MyEmployee");
+ //                       ("(*Marker2*)", "DocComment: Method");                    //FAIL due to DocComment.
+                        ("(*Marker3*)", "val tuple : int * string * float * (int -> string * int)");
+                        ("(*Marker4*)", "val methodSeq : seq<(int -> string * int)>");
+                        ("(*Marker4*)", "Full name: Test.methodSeq")
+                        ]
+        this.VerifyUsingFsTestLib fileContent queries true
+
+    [<Test>]
+    member public this.``Automation.UnionAndStructFromFSProj``() =
+        let fileContent ="""module Test
+
+                            open FSTestLib
+
+                            [<EntryPoint>]
+                            let Main (args : string []) = 
+                                let p1 = FSTestLib.MyPoint(1.0, 2.0)
+                                let (p2 : FSTestLib.MyPoint) = FSTestLib.MyPoint(2.0, 3.0)
+    
+                                // TODO: Add active pattern testing
+                                let TC21 = 
+                                    // TC21 - Testing "Identifier" of "Struct" type from "F# P2P" inside "Pattern Matching"
+                                    match p1(*Marker1*) + p2 with
+                                    | p3(*Marker2*) when p3.X = 4.0 -> p2.Len
+                                    | _ as (*Marker3*)Res -> Res.Len
+    
+                                let TCs () = 
+                                    let toSun = Kilometers 149597892.0
+        
+                                    // TC22 - Testing "Identifier" of "Union" type from "F# P2P" inside "Imperative" context
+                                    if MyDistance.toMiles toSun(*Marker4*) > toSun then
+                                        failwith "Distance in miles can't be bigger than in kilometers."
+            
+                                    let distances : MyDistance list = [toSun; toSun.toNautical; MyDistance.toMiles toSun];
+                                    for element(*Marker5*) in distances do
+                                        ()
+
+                                    // TC28 - Testing "Method" of "Union" type from "F# P2P" inside "Pattern Matching"
+                                    match MyDistance.toMiles(*Marker6*) toSun with
+                                    | Miles x ->
+                                        toSun.IncreaseBy(*Marker7*) 1.0
+                                        |> sprintf "Such a distance to Earth [%A] would mean end of world!" |> ignore
+                                    | _ ->
+                                        failwith "the previos method should have returned Miles type"
+        
+                                    // TC26 - Testing "Property" of "Union" type from "F# P2P" inside "Comp Expression"
+                                    async {
+                                        let res = toSun.toNautical(*Marker8*)
+                                        return res
+                                    }
+                                0"""
+        let queries =  [("(*Marker1*)", "val p1 : MyPoint");
+                        //("(*Marker1*)", "implements: System.IComparable");
+                        ("(*Marker2*)", "val p3 : MyPoint");
+                        //("(*Marker2*)", "type: MyPoint");
+                        //("(*Marker2*)", "inherits: System.ValueType");
+                        ("(*Marker4*)", "val toSun : MyDistance");
+                        //("(*Marker4*)", "type: MyDistance");
+                        //("(*Marker4*)", "implements: System.IComparable");
+                        ("(*Marker5*)", "val element : MyDistance");
+                        //("(*Marker5*)", "type: MyDistance");
+                        ("(*Marker6*)", "static member MyDistance.toMiles : x:MyDistance -> MyDistance");
+//                        ("(*Marker6*)", "DocComment: Static Method"); //FAIL due to DocComment
+                        ("(*Marker7*)", "member MyDistance.IncreaseBy : dist:float -> MyDistance");
+//                        ("(*Marker7*)", "DocComment: Method");    //FAIL due to DocComment
+                        ("(*Marker8*)", "property MyDistance.toNautical: MyDistance");
+//                        ("(*Marker8*)", "DocComment: Property");    //FAIL due to DocComment
+                        ]
+        this.VerifyUsingFsTestLib fileContent queries true
+
+(*------------------------------------------IDE Query automation start -------------------------------------------------*)
+
+    member private this.AssertQuickInfoInQuery(code: string, mark : string, expectedstring : string) =
+        use _guard = this.UsingNewVS()
+        let datacode = """
+        namespace DataSource
+        open System
+        open System.Xml.Linq
+
+        type Product() =
+            let mutable id = 0
+            let mutable name = ""
+            let mutable category = ""
+            let mutable price = 0M
+            let mutable unitsInStock = 0
+            member x.ProductID with get() = id and set(v) = id <- v
+            member x.ProductName with get() = name and set(v) = name <- v
+            member x.Category with get() = category and set(v) = category <- v
+            member x.UnitPrice with get() = price and set(v) = price <- v
+            member x.UnitsInStock with get() = unitsInStock and set(v) = unitsInStock <- v
+
+        module Products =
+            let getProductList() =
+                [
+                Product(ProductID = 1, ProductName = "Chai", Category = "Beverages", UnitPrice = 18.0000M, UnitsInStock = 39 );
+                Product(ProductID = 2, ProductName = "Chang", Category = "Beverages", UnitPrice = 19.0000M, UnitsInStock = 17 ); 
+                Product(ProductID = 3, ProductName = "Aniseed Syrup", Category = "Condiments", UnitPrice = 10.0000M, UnitsInStock = 13 );
+                ] 
+        """
+        let solution = this.CreateSolution()
+        let project = CreateProject(solution,"testproject")
+        this.AddAssemblyReference(project, "System.Xml.Linq")
+        let file1 = AddFileFromTextBlob(project,"File1.fs",datacode)
+        //build
+        let file2 = AddFileFromTextBlob(project,"File2.fs",code)
+        let file1 = OpenFile(project,"File1.fs")
+        let file2 = OpenFile(project,"File2.fs")
+        
+        let gpatcc = GlobalParseAndTypeCheckCounter.StartNew(this.VS)
+        MoveCursorToStartOfMarker(file2,mark)
+        let tooltip = time1 GetQuickInfoAtCursor file2 "Time of first tooltip"
+        printfn "%s" tooltip
+        AssertContains(tooltip, expectedstring) 
+        gpatcc.AssertExactly(0,0)   
+
+
+    [<Test>]
+    [<Category("Query")>]
+    [<Ignore("bug196137:Wrong type quickinfo in the query with errors elsewhere")>]
+    // QuickInfo still works on valid operators in a query with errors elsewhere in it
+    member public this.``Query.WithError1.Bug196137``() =
+        let fileContent ="""
+            open DataSource
+            // get the product list, defined in another file, see AssertQuickInfoInQuery
+            let products = Products.getProductList() 
+            let sortedProducts =
+                query {
+                    for p in products do
+                    let x = p.ProductID + "a"
+                    sortBy p.ProductName(*Mark*)
+                    select p
+                }"""
+        this.AssertQuickInfoInQuery (fileContent, "(*Mark*)", "Product.ProductName: string")
+
+    [<Test>]
+    [<Category("Query")>]
+    // QuickInfo still works on valid operators in a query with errors elsewhere in it
+    member public this.``Query.WithError2``() =
+        let fileContent ="""
+            open DataSource
+            let products = Products.getProductList()
+            let test = 
+                query {
+                    for p in products do
+                    let x = p.ProductID + "1"
+                    minBy(*Mark*) p.UnitPrice 
+                    }"""
+        this.AssertQuickInfoInQuery (fileContent, "(*Mark*)", "custom operation: minBy ('Value)")
+
+    [<Test>]
+    [<Category("Query")>]
+    // QuickInfo works in a large query (using many operators)
+    member public this.``Query.WithinLargeQuery``() =
+        let fileContent ="""
+            open DataSource
+            let products = Products.getProductList()
+            let numbers = [ 1;2; 8; 9; 15; 23; 3; 42; 4;0; 55;]
+            let largequery =
+                query {
+                    for p in products do
+                    sortBy p.ProductName
+                    thenBy p.UnitPrice
+                    thenByDescending p.Category
+                    where (p.UnitsInStock < 100)
+                    where (p.Category = "Condiments")
+                    groupValBy(*Mark1*) p p.Category into g
+                    let maxPrice = query { for x in g do maxBy(*Mark2*) x.UnitPrice }
+                    let mostExpensiveProducts = query { for x in g do where (x.UnitPrice = maxPrice) }
+                    select (g.Key, mostExpensiveProducts, query {
+                                                                for n in numbers do
+                                                                where (n%2 = 0)
+                                                                where(*Mark3*) (n > 2)
+                                                                where (n < 40)
+                                                                select n})
+                    distinct(*Mark4*)
+                }"""
+        this.AssertQuickInfoInQuery (fileContent, "(*Mark1*)", "custom operation: groupValBy ('Value) ('Key)")
+        this.AssertQuickInfoInQuery (fileContent, "(*Mark2*)", "custom operation: maxBy ('Value)")
+        this.AssertQuickInfoInQuery (fileContent, "(*Mark3*)", "custom operation: where (bool)")
+        this.AssertQuickInfoInQuery (fileContent, "(*Mark4*)", "custom operation: distinct")
+
+    [<Test>]
+    [<Category("Query")>]
+    // Arguments to query operators have correct QuickInfo
+    // quickinfo should be corroct including when the operator is causing an error
+    member public this.``Query.ArgumentToQuery.OperatorError``() =
+        let fileContent ="""
+            let numbers = [ 1;2; 8; 9; 15; 23; 3; 42; 4;0; 55;]
+            let foo = 
+                query {
+                    for n in numbers do
+                    orderBy (n.GetType())
+                    select n}"""
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "n.GetType()", "val n : int",queryAssemblyRefs)
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "Type()", "System.Object.GetType() : System.Type",queryAssemblyRefs)
+
+    [<Test>]
+    [<Category("Query")>]
+    // Arguments to query operators have correct QuickInfo
+    // quickinfo should be corroct In a nested query
+    member public this.``Query.ArgumentToQuery.InNestedQuery``() =
+        let fileContent ="""
+            open DataSource
+            let products = Products.getProductList()
+            let test1 = 
+                query {
+                    for p in products do
+                    sortBy p.ProductName
+                    select (p.ProductName, query { for f in products do
+                                                   groupValBy(*Mark3*) f f.Category into g      
+                                                   let maxPrice = query { for x in g do maxBy x.UnitPrice }
+                                                   let mostExpensiveProducts = query { for x in g do where(*Mark1*) (x.UnitPrice = maxPrice(*Mark2*)) }
+                                                   select(*Mark4*) (g.Key, g)}) } """
+        this.AssertQuickInfoInQuery (fileContent, "(*Mark1*)", "custom operation: where (bool)")
+        this.AssertQuickInfoInQuery (fileContent, "(*Mark2*)", "val maxPrice : decimal")
+        this.AssertQuickInfoInQuery (fileContent, "(*Mark3*)", "custom operation: groupValBy ('Value) ('Key)")
+        this.AssertQuickInfoInQuery (fileContent, "(*Mark4*)", "custom operation: select ('Result)")
+
+    [<Test>]
+    [<Category("Query")>]
+    // A computation expression with its own custom operators has correct QuickInfo displayed
+    member public this.``Query.ComputationExpression.Method``() =
+        let fileContent ="""
+            open System.Collections.Generic
+            let chars = ["A";"B";"C"]
+            type WorkflowBuilder() =
+
+                let yieldedItems = new List<string>()
+                member this.Items = yieldedItems |> Array.ofSeq
+
+                member this.Yield(item) = yieldedItems.Add(item)
+                member this.YieldFrom(items : seq<string>) = 
+                    items |> Seq.iter (fun item -> yieldedItems.Add(item.ToUpper()))
+                    ()
+
+                member this.Combine(f, g) = g
+                member this.Delay (f : unit -> 'a) =
+                    f()
+
+                member this.Zero() = ()
+                member this.Return _ = this.Items
+
+            let computationExpreQuery = 
+                query {
+                        for char in chars do
+                        let workflow = new WorkflowBuilder()
+                        let result =
+                            workflow {
+                                yield "foo"
+                                yield "bar"
+                                yield! [| "a"; "b"; "c" |]
+        
+                                return ()
+                            }
+                        let t = workflow.Combine(*Mark1*)("a","b")
+                        let d = workflow.Zero(*Mark2*)()
+                        where (result |> Array.exists(fun i -> i = char)) 
+                        yield char
+                       } """
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Mark1*)", "member WorkflowBuilder.Combine : f:'b * g:'c -> 'c",queryAssemblyRefs)
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Mark2*)", "member WorkflowBuilder.Zero : unit -> unit",queryAssemblyRefs)
+
+    [<Test>]
+    [<Category("Query")>]
+    // A computation expression with its own custom operators has correct QuickInfo displayed
+    member public this.``Query.ComputationExpression.CustomOp``() =
+        let fileContent ="""
+            open System
+            open Microsoft.FSharp.Quotations
+
+            type EventBuilder() = 
+                member __.For(ev:IObservable<'T>, loop:('T -> #IObservable<'U>)) : IObservable<'U> = failwith ""
+                member __.Yield(v:'T) : IObservable<'T> = failwith ""
+                member __.Quote(v:Quotations.Expr<'T>) : Expr<'T> = v
+                member __.Run(x:Expr<'T>) = Microsoft.FSharp.Linq.RuntimeHelpers.LeafExpressionConverter.EvaluateQuotation x :?> 'T
+         
+                [<CustomOperation("myWhere",MaintainsVariableSpace=true)>]
+                member __.Where (x, [<ProjectionParameter>] f) = Observable.filter f x
+         
+                [<CustomOperation("mySelect")>]
+                member __.Select (x, [<ProjectionParameter>] f) = Observable.map f x
+
+                [<CustomOperation("scanSumBy")>]
+                member inline __.ScanSumBy (source, [<ProjectionParameter>] f : 'T -> 'U) : IObservable<'U> = Observable.scan (fun a b -> a + f b) LanguagePrimitives.GenericZero<'U> source
+ 
+            let myquery = EventBuilder()
+            let f = new Event<int * int >()
+            let e1 =     
+                myquery { for x in f.Publish do 
+                            myWhere(*Mark1*) (fst x < 100)
+                            scanSumBy(*Mark2*) (snd x)
+                            } """
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Mark1*)", "custom operation: myWhere (bool)")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Mark1*)", "Calls EventBuilder.Where")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Mark2*)", "custom operation: scanSumBy ('U)")
+        this.AssertQuickInfoContainsAtStartOfMarker (fileContent, "(*Mark2*)", "Calls EventBuilder.ScanSumBy")
+
+
+(*------------------------------------------IDE automation ends here ---------------------------------------------------*)
+
+// Allow the QuickInfoTests run under different context
+namespace UnitTests.Tests.LanguageService.QuickInfo
+open UnitTests.Tests.LanguageService
+open UnitTests.TestLib.LanguageService
+open UnitTests.TestLib.ProjectSystem
+open NUnit.Framework
+open Salsa.Salsa
+
+// context msbuild
+[<TestFixture>] 
+[<Category("LanguageService.MSBuild")>]
+type ``MSBuild`` = 
+   inherit QuickInfoTests
+   new() = { inherit QuickInfoTests(VsOpts = fst (Models.MSBuild())); }
+
+// Context project system
+[<TestFixture>] 
+[<Category("LanguageService.ProjectSystem")>]
+type ``ProjectSystem`` = 
+    inherit QuickInfoTests
+    new() = { inherit QuickInfoTests(VsOpts = LanguageServiceExtension.ProjectSystem); } 
diff --git a/vsintegration/src/unittests/Tests.LanguageService.QuickParse.fs b/vsintegration/src/unittests/Tests.LanguageService.QuickParse.fs
new file mode 100644
index 0000000..5591604
--- /dev/null
+++ b/vsintegration/src/unittests/Tests.LanguageService.QuickParse.fs
@@ -0,0 +1,171 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+namespace UnitTests.Tests
+
+open System
+open System.IO
+open NUnit.Framework
+open Microsoft.VisualStudio.FSharp.LanguageService
+
+[<TestFixture>] 
+[<Category("LanguageService.MSBuild")>]
+[<Category("LanguageService.ProjectSystem")>]
+type QuickParse() = 
+
+    let CheckIsland(tolerateJustAfter:bool, s : string, p : int, expected) =
+        let actual =
+            match QuickParse.GetCompleteIdentifierIsland tolerateJustAfter s p with
+            | Some (s, col, _) -> Some (s, col)
+            | None -> None
+        Assert.AreEqual(expected, actual)
+        
+    [<Test>]
+    member public qp.CheckGetPartialLongName() = 
+        let CheckAt(line,index,expected) = 
+            let actual = QuickParse.GetPartialLongNameEx(line,index)
+            if actual <> expected then
+                failwithf "Expected %A but got %A" expected actual
+            
+        let Check(line,expected) = 
+            CheckAt(line, line.Length-1, expected)
+    
+        do Microsoft.FSharp.Compiler.AbstractIL.Diagnostics.setDiagnosticsChannel(Some(Console.Out));
+        Check("let y = List.",(["List"], ""))
+        Check("let y = List.conc",(["List"], "conc"))
+        Check("let y = S", ([], "S"))
+        Check("S", ([], "S"))
+        Check("let y=", ([], ""))
+        Check("Console.Wr", (["Console"], "Wr"))
+        Check(" .", ([""], ""))
+        Check(".", ([""], ""))
+        Check("System.Console.Wr", (["System";"Console"],"Wr"))
+        Check("let y=f'", ([], "f'"))
+        Check("let y=SomeModule.f'", (["SomeModule"], "f'"))
+        Check("let y=Some.OtherModule.f'", (["Some";"OtherModule"], "f'"))
+        Check("let y=f'g", ([], "f'g"))
+        Check("let y=SomeModule.f'g", (["SomeModule"], "f'g"))
+        Check("let y=Some.OtherModule.f'g", (["Some";"OtherModule"], "f'g"))
+        Check("let y=FSharp.Data.File.``msft-prices.csv``", ([], ""))
+        Check("let y=FSharp.Data.File.``msft-prices.csv", (["FSharp";"Data";"File"], "msft-prices.csv"))
+        Check("let y=SomeModule.  f", (["SomeModule"], "f"))
+        Check("let y=SomeModule  .f", (["SomeModule"], "f"))
+        Check("let y=SomeModule  .  f", (["SomeModule"], "f"))
+        Check("let y=SomeModule  .", (["SomeModule"], ""))
+        Check("let y=SomeModule  .  ", (["SomeModule"], ""))
+        
+        
+    [<Test>] 
+    member public qp.CheckIsland0() = CheckIsland(true, "", -1, None)       
+    [<Test>] 
+    member public qp.CheckIsland1() = CheckIsland(false, "", -1, None)
+        
+    [<Test>] 
+    member public qp.CheckIsland2() = CheckIsland(true, "", 0, None)
+    [<Test>] 
+    member public qp.CheckIsland3() = CheckIsland(false, "", 0, None)
+        
+    [<Test>] 
+    member public qp.CheckIsland4() = CheckIsland(true, null, 0, None)
+    [<Test>] 
+    member public qp.CheckIsland5() = CheckIsland(false, null, 0, None)
+        
+    [<Test>] 
+    member public qp.CheckIsland6() = CheckIsland(false, "identifier", 0, Some("identifier",10))
+    [<Test>] 
+    member public qp.CheckIsland7() = CheckIsland(false, "identifier", 8, Some("identifier",10))
+        
+    [<Test>] 
+    member public qp.CheckIsland8() = CheckIsland(true, "identifier", 0, Some("identifier",10))
+    [<Test>] 
+    member public qp.CheckIsland9() = CheckIsland(true, "identifier", 8, Some("identifier",10))
+
+    // A place where tolerateJustAfter matters
+    [<Test>] 
+    member public qp.CheckIsland10() = CheckIsland(false, "identifier", 10, None)
+    [<Test>] 
+    member public qp.CheckIsland11() = CheckIsland(true, "identifier", 10, Some("identifier",10))
+
+    // Index which overflows the line
+    [<Test>] 
+    member public qp.CheckIsland12() = CheckIsland(true, "identifier", 11, None)
+    [<Test>] 
+    member public qp.CheckIsland13() = CheckIsland(false, "identifier", 11, None)
+    
+    // Match active pattern identifiers
+    [<Test>]
+    member public qp.CheckIsland14() = CheckIsland(false, "|Identifier|", 0, Some("|Identifier|",12))    
+    [<Test>]
+    member public qp.CheckIsland15() = CheckIsland(true, "|Identifier|", 0, Some("|Identifier|",12))        
+    [<Test>]
+    member public qp.CheckIsland16() = CheckIsland(false, "|Identifier|", 12, None)    
+    [<Test>]
+    member public qp.CheckIsland17() = CheckIsland(true, "|Identifier|", 12, Some("|Identifier|",12))        
+    [<Test>] 
+    member public qp.CheckIsland18() = CheckIsland(false, "|Identifier|", 13, None)    
+    [<Test>] 
+    member public qp.CheckIsland19() = CheckIsland(true, "|Identifier|", 13, None)        
+    
+    // ``Quoted`` identifiers
+    [<Test>]
+    member public qp.CheckIsland20() = CheckIsland(false, "``Space Man``", 0, Some("``Space Man``",13))    
+    [<Test>]
+    member public qp.CheckIsland21() = CheckIsland(true, "``Space Man``", 0, Some("``Space Man``",13))    
+    [<Test>]
+    member public qp.CheckIsland22() = CheckIsland(false, "``Space Man``", 10, Some("``Space Man``",13))    
+    [<Test>]
+    member public qp.CheckIsland23() = CheckIsland(true, "``Space Man``", 10, Some("``Space Man``",13))    
+    [<Test>]
+    member public qp.CheckIsland24() = CheckIsland(false, "``Space Man``", 11, Some("``Space Man``",13))    
+    // [<Test>]
+    // member public qp.CheckIsland25() = CheckIsland(true, "``Space Man``", 11, Some("Man",11))  // This is probably not what the user wanted. Not enforcing this test.
+    [<Test>]
+    member public qp.CheckIsland26() = CheckIsland(false, "``Space Man``", 12, Some("``Space Man``",13))    
+    [<Test>]
+    member public qp.CheckIsland27() = CheckIsland(true, "``Space Man``", 12, Some("``Space Man``",13))    
+    [<Test>]
+    member public qp.CheckIsland28() = CheckIsland(false, "``Space Man``", 13, None)    
+    [<Test>]
+    member public qp.CheckIsland29() = CheckIsland(true, "``Space Man``", 13, Some("``Space Man``",13))    
+    [<Test>] 
+    member public qp.CheckIsland30() = CheckIsland(false, "``Space Man``", 14, None)    
+    [<Test>] 
+    member public qp.CheckIsland31() = CheckIsland(true, "``Space Man``", 14, None)    
+    [<Test>] 
+    member public qp.CheckIsland32() = CheckIsland(true, "``msft-prices.csv``", 14, Some("``msft-prices.csv``",19))    
+    // handle extracting islands from arrays    
+    [<Test>] 
+    member public qp.CheckIsland33() = CheckIsland(true, "[|abc;def|]", 2, Some("abc",5))    
+    [<Test>] 
+    member public qp.CheckIsland34() = CheckIsland(true, "[|abc;def|]", 4, Some("abc",5))    
+    [<Test>] 
+    member public qp.CheckIsland35() = CheckIsland(true, "[|abc;def|]", 5, Some("abc",5))    
+    [<Test>] 
+    member public qp.CheckIsland36() = CheckIsland(true, "[|abc;def|]", 6, Some("def",9))    
+    [<Test>] 
+    member public qp.CheckIsland37() = CheckIsland(true, "[|abc;def|]", 8, Some("def",9))    
+    [<Test>] 
+    member public qp.CheckIsland38() = CheckIsland(true, "[|abc;def|]", 9, Some("def",9))    
+    [<Test>] 
+    member public qp.CheckIsland39() = CheckIsland(false, "identifier(*boo*)", 0, Some("identifier",10))
+    [<Test>] 
+    member public qp.CheckIsland40() = CheckIsland(true, "identifier(*boo*)", 0, Some("identifier",10))
+    [<Test>] 
+    member public qp.CheckIsland41() = CheckIsland(false, "identifier(*boo*)", 10, None)
+    [<Test>] 
+    member public qp.CheckIsland42() = CheckIsland(true, "identifier(*boo*)", 10, Some("identifier",10))
+    [<Test>] 
+    member public qp.CheckIsland43() = CheckIsland(false, "identifier(*boo*)", 11, None)
+    [<Test>] 
+    member public qp.CheckIsland44() = CheckIsland(true, "identifier(*boo*)", 11, None)
+    [<Test>] 
+    member public qp.CheckIsland45() = CheckIsland(false, "``Space Man (*boo*)``", 13, Some("``Space Man (*boo*)``",21))
+    [<Test>] 
+    member public qp.CheckIsland46() = CheckIsland(true, "``Space Man (*boo*)``", 13, Some("``Space Man (*boo*)``",21))
+    [<Test>] 
+    member public qp.CheckIsland47() = CheckIsland(false, "(*boo*)identifier", 11, Some("identifier",17))
+    [<Test>] 
+    member public qp.CheckIsland48() = CheckIsland(true, "(*boo*)identifier", 11, Some("identifier",17))
+    [<Test>] 
+    member public qp.CheckIsland49() = CheckIsland(false, "identifier(*(*  *)boo*)", 0, Some("identifier",10))
+    [<Test>] 
+    member public qp.CheckIsland50() = CheckIsland(true, "identifier(*(*  *)boo*)", 0, Some("identifier",10))
diff --git a/vsintegration/src/unittests/Tests.LanguageService.Script.fs b/vsintegration/src/unittests/Tests.LanguageService.Script.fs
new file mode 100644
index 0000000..b019a44
--- /dev/null
+++ b/vsintegration/src/unittests/Tests.LanguageService.Script.fs
@@ -0,0 +1,1641 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+namespace UnitTests.Tests.LanguageService
+
+open System
+open System.IO
+open NUnit.Framework
+open Salsa.Salsa
+open Salsa.VsOpsUtils
+open UnitTests.TestLib.Salsa
+open UnitTests.TestLib.Utils
+open UnitTests.TestLib.LanguageService
+
+type ScriptTests() as this = 
+    inherit LanguageServiceBaseTests() 
+
+    let notAA l = None,l
+
+    let createSingleFileFsx (code : string) = 
+        let (_, p, f) = this.CreateSingleFileProject(code, fileKind = SourceFileKind.FSX)
+        (p, f)
+
+    let createSingleFileFsxFromLines (code : list<string>) = 
+        let (_, p, f) = this.CreateSingleFileProject(code, fileKind = SourceFileKind.FSX)
+        (p, f)
+
+    (* Timings ----------------------------------------------------------------------------- *)
+    let stopWatch = new System.Diagnostics.Stopwatch()
+    let ResetStopWatch() = stopWatch.Reset(); stopWatch.Start()
+    let time1 op a message = 
+        ResetStopWatch()
+        let result = op a
+        printf "%s %d ms\n" message stopWatch.ElapsedMilliseconds
+        result
+
+    let ShowErrors(project:OpenProject) =     
+        for error in (GetErrors(project)) do
+            printf "%s\n" (error.ToString())  
+
+    let AssertListContainsInOrder(s:string list,cs:string list) =
+        let s : string array = Array.ofList s
+        let s : string = String.Join("\n",s)
+        AssertContainsInOrder(s,cs)
+
+    /// Assert that there is no squiggle.
+    let AssertNoSquiggle(squiggleOption) = 
+        match squiggleOption with 
+        | None -> ()
+        | Some(severity,message) ->
+            Assert.Fail(sprintf "Expected no squiggle but got '%A' with message: %s" severity message)
+
+    let VerifyErrorListContainedExpetedStr(expectedStr:string,project : OpenProject) = 
+        let errorList = GetErrors(project)
+        let GetErrorMessages(errorList : Error list) =
+            [ for i = 0 to errorList.Length - 1 do
+                yield errorList.[i].Message]
+            
+        Assert.IsTrue(errorList
+                          |> GetErrorMessages
+                          |> Seq.exists (fun errorMessage ->
+                                errorMessage.Contains(expectedStr)))
+
+    let AssertNoErrorsOrWarnings(project:OpenProject) = 
+        let count = List.length (GetErrors(project))
+        if count<>0 then
+            printf "Saw %d errors and expected none.\n" count
+            printf "Errors are: \n" 
+            for e in GetErrors project do 
+                printf "  path = <<<%s>>>\n" e.Path
+                printf "  message = <<<%s> \n" e.Message 
+            AssertEqual(0,count)
+
+    let AssertExactlyOneErrorSeenContaining(project:OpenProject,text) =
+        let nMatching = (GetErrors(project)) |> List.filter (fun e ->e.ToString().Contains(text)) |> List.length
+        match nMatching with
+        | 0 -> 
+            failwith (sprintf "No errors containing \"%s\"" text)
+        | 1 -> ()
+        | _ -> 
+            failwith (sprintf "Multiple errors containing \"%s\"" text)
+
+    /// Assert that a given squiggle is an Error (or warning) containing the given text        
+    let AssertSquiggleIsErrorContaining,AssertSquiggleIsWarningContaining, AssertSquiggleIsErrorNotContaining,AssertSquiggleIsWarningNotContaining =         
+        let AssertSquiggle expectedSeverity nameOfExpected nameOfNotExpected assertf (squiggleOption,containing) = 
+            match squiggleOption with
+            | None -> Assert.Fail("Expected a squiggle but none was seen.")
+            | Some(severity,message) ->
+                Assert.IsTrue((severity=expectedSeverity), sprintf "Expected %s but saw %s: %s" nameOfExpected nameOfNotExpected message)
+                assertf(message,containing)        
+        AssertSquiggle Microsoft.VisualStudio.FSharp.LanguageService.Severity.Error    "Error"    "Warning" AssertContains,
+        AssertSquiggle Microsoft.VisualStudio.FSharp.LanguageService.Severity.Warning  "Warning"  "Error"   AssertContains,
+        AssertSquiggle Microsoft.VisualStudio.FSharp.LanguageService.Severity.Error    "Error"    "Warning" AssertNotContains,
+        AssertSquiggle Microsoft.VisualStudio.FSharp.LanguageService.Severity.Warning  "Warning"  "Error"   AssertNotContains 
+
+
+    //Verify the error list in fsx file containd the expected string
+    member private this.VerifyFSXErrorListContainedExpectedString(fileContents : string, expectedStr : string) =
+        let (_, project, file) = this.CreateSingleFileProject(fileContents, fileKind = SourceFileKind.FSX)
+        VerifyErrorListContainedExpetedStr(expectedStr,project)    
+
+    //Verify no error list in fsx file 
+    member private this.VerifyFSXNoErrorList(fileContents : string) =
+        let (_, project, file) = this.CreateSingleFileProject(fileContents, fileKind = SourceFileKind.FSX)
+        AssertNoErrorsOrWarnings(project)  
+    //Verify QuickInfo Containd In Fsx file
+    member public this.AssertQuickInfoContainsAtEndOfMarkerInFsxFile (code : string) marker expected =
+
+        let (_, _, file) = this.CreateSingleFileProject(code, fileKind = SourceFileKind.FSX)
+
+        MoveCursorToEndOfMarker(file, marker)
+        let tooltip = GetQuickInfoAtCursor file
+        AssertContains(tooltip, expected)
+    //Verify QuickInfo Containd In Fsx file
+    member public this.AssertQuickInfoContainsAtStartOfMarkerInFsxFile (code : string) marker expected =
+        let (_, _, file) = this.CreateSingleFileProject((code : string), fileKind = SourceFileKind.FSX)
+
+        MoveCursorToStartOfMarker(file, marker)
+        let tooltip = GetQuickInfoAtCursor file
+        AssertContains(tooltip, expected)
+    //Verify QuickInfo Not Containd In Fsx file     
+    member public this.AssertQuickInfoNotContainsAtEndOfMarkerInFsxFile code marker notexpected =
+        let (_, _, file) = this.CreateSingleFileProject((code : string), fileKind = SourceFileKind.FSX)
+
+        MoveCursorToEndOfMarker(file, marker)
+        let tooltip = GetQuickInfoAtCursor file
+        AssertNotContains(tooltip, notexpected)
+
+    /// There was a problem with Salsa that caused squiggles not to be shown for .fsx files.
+    [<Test>]
+    member public this.``Fsx.Squiggles.ShowInFsxFiles``() =  
+        let fileContent = """open Thing1.Thing2"""
+        this.VerifyFSXErrorListContainedExpectedString(fileContent,"Thing1")
+        
+    /// Regression test for FSharp1.0:4861 - #r to non-existent file causes the first line to be squiggled
+    /// There was a problem with Salsa that caused squiggles not to be shown for .fsx files.
+    [<Test>]
+    member public this.``Fsx.Hash.RProperSquiggleForNonExistentFile``() =  
+        let fileContent = """#r "NonExistent" """
+        this.VerifyFSXErrorListContainedExpectedString(fileContent,"was not found or is invalid") 
+
+    /// Nonexistent hash. There was a problem with Salsa that caused squiggles not to be shown for .fsx files.
+    [<Test>]
+    member public this.``Fsx.Hash.RDoesNotExist.Bug3325``() =  
+        let fileContent = """#r "ThisDLLDoesNotExist" """
+        this.VerifyFSXErrorListContainedExpectedString(fileContent,"'ThisDLLDoesNotExist' was not found or is invalid") 
+
+    // There was a spurious error message on the first line.
+    [<Test>]
+    [<Category("fsx closure")>]
+    member public this.``Fsx.ExactlyOneError.Bug4861``() =  
+        let code = 
+                                      ["#light" // First line is important in this repro
+                                       "#r \"Nonexistent\""
+                                       ]
+        let (project, _) = createSingleFileFsxFromLines code
+        AssertExactlyOneErrorSeenContaining(project, "Nonexistent")   // ...and not an error on the first line.
+        
+    [<Test>]
+    member public this.``Fsx.InvalidHashLoad.ShouldBeASquiggle.Bug3012``() =  
+        let fileContent = """
+            #light
+            #load "Bar.fs"
+            """
+        this.VerifyFSXErrorListContainedExpectedString(fileContent,"Bar.fs") 
+
+    // Transitive to existing property.
+    [<Test>]
+    [<Category("fsx closure")>]
+    member public this.``Fsx.ScriptClosure.TransitiveLoad1``() = 
+        use _guard = this.UsingNewVS() 
+        let solution = this.CreateSolution()
+        let project = CreateProject(solution,"testproject")    
+        let file1 = AddFileFromText(project,"File1.fs",
+                                    ["namespace Namespace"
+                                     "type Foo = "
+                                     "     static member public Property = 0"
+                                     ])    
+        let file1 = OpenFile(project,"File1.fs")   
+        let script2 = AddFileFromText(project,"Script2.fsx",
+                                      ["#load \"File1.fs\""
+                                       ])    
+        let script2 = OpenFile(project,"Script2.fsx")   
+        let script2 = AddFileFromText(project,"Script1.fsx",
+                                      ["#load \"Script1.fsx\""
+                                       "Namespace.Foo.Property" 
+                                       ])    
+        let script2 = OpenFile(project,"Script2.fsx")   
+        TakeCoffeeBreak(this.VS)
+        AssertNoErrorsOrWarnings(project)
+
+    // Transitive to nonexisting property.
+    [<Test>]
+    [<Category("fsx closure")>]
+    member public this.``Fsx.ScriptClosure.TransitiveLoad2``() = 
+        use _guard = this.UsingNewVS()  
+        let solution = this.CreateSolution()
+        let project = CreateProject(solution,"testproject")    
+        let file1 = AddFileFromText(project,"File1.fs",
+                                    ["namespace Namespace"
+                                     "type Foo = "
+                                     "     static member public Property = 0"
+                                     ])    
+        let script2 = AddFileFromText(project,"Script2.fsx",
+                                      ["#load \"File1.fs\""
+                                       ])    
+        let script1 = AddFileFromText(project,"Script1.fsx",
+                                      ["#load \"Script2.fsx\""
+                                       "Namespace.Foo.NonExistingProperty" 
+                                       ])    
+        let script1 = OpenFile(project,"Script1.fsx")   
+        TakeCoffeeBreak(this.VS)
+        AssertExactlyOneErrorSeenContaining(project, "NonExistingProperty")
+
+    /// FEATURE: Typing a #r into a file will cause it to be recognized by intellisense.
+    [<Test>]
+    [<Category("fsx closure")>]
+    member public this.``Fsx.HashR.AddedIn``() =  
+        let code =
+                                    ["#light"
+                                     "//#r \"System.Transactions.dll\"" // Pick anything that isn't in the standard set of assemblies.
+                                     "open System.Transactions"
+                                     ]
+        let (project, file) = createSingleFileFsxFromLines code
+        VerifyErrorListContainedExpetedStr("Transactions",project)
+        
+        let gpatcc = GlobalParseAndTypeCheckCounter.StartNew(this.VS)
+        ReplaceFileInMemory file
+                        ["#light"
+                         "#r \"System.Transactions.dll\"" // <-- Uncomment this line
+                         "open System.Transactions"
+                         ]
+        AssertNoErrorsOrWarnings(project)
+        gpatcc.AssertExactly(notAA[file],notAA[file], true (* expectDelete, because dependent DLL set changed *))
+
+    // FEATURE: Adding a #load to a file will cause types from that file to be visible in intellisense
+    [<Test>]
+    member public this.``Fsx.HashLoad.Added``() =  
+        use _guard = this.UsingNewVS()
+        let solution = this.CreateSolution()
+        let project = CreateProject(solution,"testproject")
+        let fs = AddFileFromText(project,"File1.fs",
+                                    ["#light"
+                                     "namespace MyNamespace" 
+                                     "    module MyModule ="
+                                     "        let x = 1" 
+                                     ])            
+        
+        let fsx = AddFileFromText(project,"File2.fsx",
+                                    ["#light"
+                                     "//#load \"File1.fs\"" 
+                                     "open MyNamespace.MyModule"
+                                     "printfn \"%d\" x"
+                                     ])    
+        let fsx = OpenFile(project,"File2.fsx")    
+        VerifyErrorListContainedExpetedStr("MyNamespace",project)
+        
+        ReplaceFileInMemory fsx
+                         ["#light"
+                          "#load \"File1.fs\"" 
+                          "open MyNamespace.MyModule"
+                          "printfn \"%d\" x"
+                          ]
+        TakeCoffeeBreak(this.VS)
+        AssertNoErrorsOrWarnings(project)
+
+    // FEATURE: Removing a #load to a file will cause types from that file to no longer be visible in intellisense
+    [<Test>]
+    member public this.``Fsx.HashLoad.Removed``() =  
+        use _guard = this.UsingNewVS()
+        let solution = this.CreateSolution()
+        let project = CreateProject(solution,"testproject")
+        let fs = AddFileFromText(project,"File1.fs",
+                                    ["#light"
+                                     "namespace MyNamespace" 
+                                     "    module MyModule ="
+                                     "        let x = 1" 
+                                     ])            
+        
+        let fsx = AddFileFromText(project,"File2.fsx",
+                                    ["#light"
+                                     "#load \"File1.fs\"" 
+                                     "open MyNamespace.MyModule"
+                                     "printfn \"%d\" x"
+                                     ])    
+        let fsx = OpenFile(project,"File2.fsx")    
+        AssertNoErrorsOrWarnings(project)
+        
+        ReplaceFileInMemory fsx
+                         ["#light"
+                          "//#load \"File1.fs\"" 
+                          "open MyNamespace.MyModule"
+                          "printfn \"%d\" x"
+                          ]
+        TakeCoffeeBreak(this.VS)
+        VerifyErrorListContainedExpetedStr("MyNamespace",project)
+    
+    [<Test>]
+    member public this.``Fsx.HashLoad.Conditionals``() =
+        use _guard = this.UsingNewVS()
+        let solution = this.CreateSolution()
+        let project = CreateProject(solution,"testproject")
+        let fs = AddFileFromText(project,"File1.fs",
+                                    ["module InDifferentFS"
+                                     "#if INTERACTIVE"
+                                     "let x = 1"
+                                     "#else"
+                                     "let y = 2"
+                                     "#endif"
+                                     "#if DEBUG"
+                                     "let A = 3"
+                                     "#else"
+                                     "let B = 4"
+                                     "#endif"
+                                     ])            
+        
+        let fsx = AddFileFromText(project,"File2.fsx",
+                                    [
+                                     "#load \"File1.fs\"" 
+                                     "InDifferentFS."
+                                     ])    
+        let fsx = OpenFile(project,"File2.fsx")
+
+        MoveCursorToEndOfMarker(fsx, "InDifferentFS.")
+        let completion = AutoCompleteAtCursor fsx
+        let completion = completion |> Array.map (fun (name, _, _, _) -> name) |> set
+        Assert.AreEqual(Set.count completion, 2, "Expected 2 elements in the completion list")
+        Assert.IsTrue(completion.Contains "x", "Completion list should contain x because INTERACTIVE is defined")
+        Assert.IsTrue(completion.Contains "B", "Completion list should contain B because DEBUG is not defined")
+        
+
+    /// FEATURE: Removing a #r into a file will cause it to no longer be seen by intellisense.
+    [<Test>]
+    [<Category("fsx closure")>]
+    member public this.``Fsx.HashR.Removed``() =  
+        let code =
+                                    ["#light"
+                                     "#r \"System.Transactions.dll\"" // Pick anything that isn't in the standard set of assemblies.
+                                     "open System.Transactions"
+                                     ]
+        let (project, file) = createSingleFileFsxFromLines code
+        TakeCoffeeBreak(this.VS)
+        AssertNoErrorsOrWarnings(project)  
+        
+        let gpatcc = GlobalParseAndTypeCheckCounter.StartNew(this.VS)
+        ReplaceFileInMemory file
+                        ["#light"
+                         "//#r \"System.Transactions.dll\"" // <-- Comment this line
+                         "open System.Transactions"
+                         ]
+        SaveFileToDisk(file)
+        TakeCoffeeBreak(this.VS)
+        VerifyErrorListContainedExpetedStr("Transactions",project)
+        gpatcc.AssertExactly(notAA[file], notAA[file], true (* expectDelete, because dependent DLL set changed *))
+    
+
+
+    // Corecursive load to existing property.
+    [<Test>]
+    [<Category("fsx closure")>]
+    member public this.``Fsx.NoError.ScriptClosure.TransitiveLoad3``() =  
+        use _guard = this.UsingNewVS()
+        let solution = this.CreateSolution()
+        let project = CreateProject(solution,"testproject")    
+        let file1 = AddFileFromText(project,"File1.fs",
+                                    ["namespace Namespace"
+                                     "type Foo = "
+                                     "     static member public Property = 0"
+                                     ])    
+        let script2 = AddFileFromText(project,"Script2.fsx",
+                                      ["#load \"Script1.fsx\""
+                                       "#load \"File1.fs\""
+                                       ])    
+        let script1 = AddFileFromText(project,"Script1.fsx",
+                                      ["#load \"Script2.fsx\""
+                                       "#load \"File1.fs\""
+                                       "Namespace.Foo.Property" 
+                                       ])    
+        let script1 = OpenFile(project,"Script1.fsx")   
+        TakeCoffeeBreak(this.VS)
+        AssertNoErrorsOrWarnings(project)
+        
+    // #load of .fsi is respected (for non-hidden property)
+    [<Test>]
+    [<Category("fsx closure")>]
+    member public this.``Fsx.NoError.ScriptClosure.TransitiveLoad9``() =  
+        use _guard = this.UsingNewVS()
+        let solution = this.CreateSolution()
+        let project = CreateProject(solution,"testproject")    
+        let file1fsi = AddFileFromText(project,"File1.fsi",
+                                      ["namespace Namespace"
+                                       "type Foo ="
+                                       "  class"
+                                       "    static member Property : int" // Not exposing 'HiddenProperty'
+                                       "  end"
+                                       ])            
+        let file1 = AddFileFromText(project,"File1.fs",
+                                    ["namespace Namespace"
+                                     "type Foo = "
+                                     "     static member public HiddenProperty = 0"
+                                     "     static member public Property = 0"
+                                     ])    
+
+        let script1 = AddFileFromText(project,"Script1.fsx",
+                                      ["#load \"File1.fsi\""
+                                       "#load \"File1.fs\""
+                                       "Namespace.Foo.Property" 
+                                       ])     
+        let script1 = OpenFile(project,"Script1.fsx")   
+        AssertNoErrorsOrWarnings(project) 
+
+    // #load of .fsi is respected at second #load level (for non-hidden property) 
+    [<Test>]
+    [<Category("fsx closure")>]
+    member public this.``Fsx.NoError.ScriptClosure.TransitiveLoad10``() =  
+        use _guard = this.UsingNewVS()
+        let solution = this.CreateSolution()
+        let project = CreateProject(solution,"testproject")    
+        let file1fsi = AddFileFromText(project,"File1.fsi",
+                                      ["namespace Namespace"
+                                       "type Foo ="
+                                       "  class"
+                                       "    static member Property : int" // Not exposing 'HiddenProperty'
+                                       "  end"
+                                       ])            
+        let file1 = AddFileFromText(project,"File1.fs",
+                                    ["namespace Namespace"
+                                     "type Foo = "
+                                     "     static member public HiddenProperty = 0"
+                                     "     static member public Property = 0"
+                                     ])    
+
+        let script1 = AddFileFromText(project,"Script1.fsx",
+                                      ["#load \"File1.fsi\""
+                                       "#load \"File1.fs\""
+                                       ])     
+        let script2 = AddFileFromText(project,"Script2.fsx",
+                                      ["#load \"Script1.fsx\""
+                                       "Namespace.Foo.Property" 
+                                       ])    
+        let script2 = OpenFile(project,"Script2.fsx")   
+        AssertNoErrorsOrWarnings(project) 
+
+    // #load of .fsi is respected when dispersed between two #load levels (for non-hidden property)
+    [<Test>]
+    [<Category("fsx closure")>]
+    member public this.``Fsx.NoError.ScriptClosure.TransitiveLoad11``() =  
+        use _guard = this.UsingNewVS()
+        let solution = this.CreateSolution()
+        let project = CreateProject(solution,"testproject")    
+        let file1fsi = AddFileFromText(project,"File1.fsi",
+                                      ["namespace Namespace"
+                                       "type Foo ="
+                                       "  class"
+                                       "    static member Property : int" // Not exposing 'HiddenProperty'
+                                       "  end"
+                                       ])            
+        let file1 = AddFileFromText(project,"File1.fs",
+                                    ["namespace Namespace"
+                                     "type Foo = "
+                                     "     static member public HiddenProperty = 0"
+                                     "     static member public Property = 0"
+                                     ])    
+
+        let script1 = AddFileFromText(project,"Script1.fsx",
+                                      ["#load \"File1.fsi\""
+                                       ])     
+        let script2 = AddFileFromText(project,"Script2.fsx",
+                                      ["#load \"Script1.fsx\""
+                                       "#load \"File1.fs\""
+                                       "Namespace.Foo.Property" 
+                                       ])    
+        let script2 = OpenFile(project,"Script2.fsx")   
+        AssertNoErrorsOrWarnings(project)  
+        
+    // #load of .fsi is respected when dispersed between two #load levels (the other way) (for non-hidden property)
+    [<Test>]
+    [<Category("fsx closure")>]
+    member public this.``Fsx.NoError.ScriptClosure.TransitiveLoad12``() =  
+        use _guard = this.UsingNewVS()
+        let solution = this.CreateSolution()
+        let project = CreateProject(solution,"testproject")    
+        let file1fsi = AddFileFromText(project,"File1.fsi",
+                                      ["namespace Namespace"
+                                       "type Foo ="
+                                       "  class"
+                                       "    static member Property : int" // Not exposing 'HiddenProperty'
+                                       "  end"
+                                       ])            
+        let file1 = AddFileFromText(project,"File1.fs",
+                                    ["namespace Namespace"
+                                     "type Foo = "
+                                     "     static member public HiddenProperty = 0"
+                                     "     static member public Property = 0"
+                                     ])    
+
+        let script1 = AddFileFromText(project,"Script1.fsx",
+                                      ["#load \"File1.fs\""
+                                       ])     
+        let script2 = AddFileFromText(project,"Script2.fsx",
+                                      ["#load \"File1.fsi\""
+                                       "#load \"Script1.fsx\""
+                                       "Namespace.Foo.Property" 
+                                       ])    
+        let script2 = OpenFile(project,"Script2.fsx")   
+        AssertNoErrorsOrWarnings(project)  
+        
+    // #nowarn seen in closed .fsx is global to the closure
+    [<Test>]
+    [<Category("fsx closure")>]
+    member public this.``Fsx.NoError.ScriptClosure.TransitiveLoad16``() =  
+        use _guard = this.UsingNewVS()
+        let solution = this.CreateSolution()
+        let project = CreateProject(solution,"testproject")    
+        let thisProject = AddFileFromText(project,"ThisProject.fsx",
+                                      ["#nowarn \"44\""
+                                       ])  
+        let script1 = AddFileFromText(project,"Script1.fsx",
+                                      ["#load \"ThisProject.fsx\"" // Should bring in #nowarn "44" so we don't see this warning:
+                                       "[<System.Obsolete(\"x\")>]"
+                                       "let fn x = 0"
+                                       "let y = fn 1"
+                                       ])                                                   
+
+        let script1 = OpenFile(project,"Script1.fsx")   
+        MoveCursorToEndOfMarker(script1,"let y = f") 
+        TakeCoffeeBreak(this.VS) 
+        AssertNoErrorsOrWarnings(project)   
+
+    /// FEATURE: #r in .fsx to a .dll name works.
+    [<Test>]
+    member public this.``Fsx.NoError.HashR.DllWithNoPath``() =  
+        let fileContent = """
+            #light
+            #r "System.Transactions.dll"
+            open System.Transactions"""
+        this.VerifyFSXNoErrorList(fileContent)
+
+
+    [<Test>]
+    // 'System' is in the default set. Make sure we can still resolve it.
+    member public this.``Fsx.NoError.HashR.BugDefaultReferenceFileIsAlsoResolved``() =  
+        let fileContent = """
+            #light
+            #r "System"
+            """
+        this.VerifyFSXNoErrorList(fileContent)
+
+    [<Test>]
+    [<Category("fsx closure")>]
+    member public this.``Fsx.NoError.HashR.DoubleReference``() =  
+        let fileContent = """
+            #light
+            #r "System"
+            #r "System"
+            """
+        this.VerifyFSXNoErrorList(fileContent)
+
+    [<Test>]
+    [<Category("fsx closure")>]
+    // 'mscorcfg' is loaded from the GAC _and_ it is available on XP and above.
+    member public this.``Fsx.NoError.HashR.ResolveFromGAC``() =  
+        let fileContent = """
+            #light
+            #r "mscorcfg"
+            """
+        this.VerifyFSXNoErrorList(fileContent)
+
+    [<Test>]
+    [<Category("fsx closure")>]
+    // 'Microsoft.TeamFoundation.Diff' is located via AssemblyFoldersEx
+    member public this.``Fsx.NoError.HashR.ResolveFromAssemblyFoldersEx``() =  
+        let fileContent = """
+            #light
+            #r "Microsoft.TeamFoundation.Diff"
+            """
+        this.VerifyFSXNoErrorList(fileContent)
+
+    [<Test>]
+    [<Category("fsx closure")>]
+    // Can be any assembly that is in AssemblyFolders but not AssemblyFoldersEx
+    member public this.``Fsx.NoError.HashR.ResolveFromAssemblyFolders``() = 
+        let fileContent = """
+            #light
+            #r "Microsoft.SqlServer.SString"
+            """
+        this.VerifyFSXNoErrorList(fileContent) 
+
+    [<Test>]
+    [<Category("fsx closure")>]
+    member public this.``Fsx.NoError.HashR.ResolveFromFullyQualifiedPath``() =         
+        let fullyqualifiepathtoddll = System.IO.Path.Combine( System.Runtime.InteropServices.RuntimeEnvironment.GetRuntimeDirectory(), "System.configuration.dll" )
+        let code = ["#light";"#r @\"" + fullyqualifiepathtoddll + "\""]
+        let (project, _) = createSingleFileFsxFromLines code
+        AssertNoErrorsOrWarnings(project)
+ 
+     /// FEATURE: #load in an .fsx file will include that file in the 'build' of the .fsx.
+    [<Test>]
+    member public this.``Fsx.NoError.HashLoad.Simple``() =  
+        use _guard = this.UsingNewVS()
+        let solution = this.CreateSolution()
+        let project = CreateProject(solution,"testproject")
+        let fs = AddFileFromText(project,"File1.fs",
+                                    ["#light"
+                                     "namespace MyNamespace" 
+                                     "    module MyModule ="
+                                     "        let x = 1" 
+                                     ])            
+        
+        let fsx = AddFileFromText(project,"File2.fsx",
+                                    ["#light"
+                                     "#load \"File1.fs\"" 
+                                     "open MyNamespace.MyModule"
+                                     "printfn \"%d\" x"
+                                     ])    
+        let fsx = OpenFile(project,"File2.fsx")    
+        AssertNoErrorsOrWarnings(project)
+
+    // In this bug the #loaded file contains a level-4 warning (copy to avoid mutation). This warning was reported at the #load in file2.fsx but shouldn't have been.s
+    [<Test>]
+    [<Category("fsx closure")>]
+    member public this.``Fsx.NoWarn.OnLoadedFile.Bug4837``() =  
+        use _guard = this.UsingNewVS()
+        let solution = this.CreateSolution()
+        let project = CreateProject(solution,"testproject")
+        let fs = AddFileFromText(project,"File1.fs",
+                                    ["module File1Module"
+                                     "let x = System.DateTime.Now - System.DateTime.Now"
+                                     "x.Add(x) |> ignore" 
+                                     ])            
+        
+        let fsx = AddFileFromText(project,"File2.fsx",
+                                    [
+                                     "#load \"File1.fs\"" 
+                                     ])    
+        let fsx = OpenFile(project,"File2.fsx")    
+        AssertNoErrorsOrWarnings(project) 
+
+    /// FEATURE: .fsx files have automatic imports of certain system assemblies.
+    //There is a test bug here. The actual scenario works. Need to revisit.
+    [<Test>]
+    [<Category("ReproX")>]  
+    member public this.``Fsx.NoError.AutomaticImportsForFsxFiles``() =
+        let fileContent = """
+            #light
+            open System
+            open System.Xml
+            open System.Drawing
+            open System.Runtime.Remoting
+            open System.Runtime.Serialization.Formatters.Soap
+            open System.Data
+            open System.Drawing
+            open System.Web
+            open System.Web.Services
+            open System.Windows.Forms"""
+        this.VerifyFSXNoErrorList(fileContent) 
+
+    // Corecursive load to nonexisting property.
+    [<Test>]
+    [<Category("fsx closure")>]
+    member public this.``Fsx.ExactlyOneError.ScriptClosure.TransitiveLoad4``() =  
+        use _guard = this.UsingNewVS()
+        let solution = this.CreateSolution()
+        let project = CreateProject(solution,"testproject")    
+        let file1 = AddFileFromText(project,"File1.fs",
+                                    ["namespace Namespace"
+                                     "type Foo = "
+                                     "     static member public Property = 0"
+                                     ])    
+        let script2 = AddFileFromText(project,"Script2.fsx",
+                                      ["#load \"Script1.fsx\""
+                                       "#load \"File1.fs\""
+                                       ])    
+        let script1 = AddFileFromText(project,"Script1.fsx",
+                                      ["#load \"Script2.fsx\""
+                                       "#load \"File1.fs\""
+                                       "Namespace.Foo.NonExistingProperty" 
+                                       ])     
+        let script1 = OpenFile(project,"Script1.fsx")   
+        AssertExactlyOneErrorSeenContaining(project, "NonExistingProperty")  
+
+    // #load of .fsi is respected
+    [<Test>]
+    [<Category("fsx closure")>]
+    member public this.``Fsx.ExactlyOneError.ScriptClosure.TransitiveLoad5``() =  
+        use _guard = this.UsingNewVS()
+        let solution = this.CreateSolution()
+        let project = CreateProject(solution,"testproject")    
+        let file1fsi = AddFileFromText(project,"File1.fsi",
+                                      ["namespace Namespace"
+                                       "type Foo ="
+                                       "  class"
+                                       "    static member Property : int" // Not exposing 'HiddenProperty'
+                                       "  end"
+                                       ])            
+        let file1 = AddFileFromText(project,"File1.fs",
+                                    ["namespace Namespace"
+                                     "type Foo = "
+                                     "     static member public HiddenProperty = 0"
+                                     "     static member public Property = 0"
+                                     ])    
+
+        let script1 = AddFileFromText(project,"Script1.fsx",
+                                      ["#load \"File1.fsi\""
+                                       "#load \"File1.fs\""
+                                       "Namespace.Foo.HiddenProperty" 
+                                       ])     
+        let script1 = OpenFile(project,"Script1.fsx")   
+        AssertExactlyOneErrorSeenContaining(project, "HiddenProperty")   
+
+    // #load of .fsi is respected at second #load level
+    [<Test>]
+    [<Category("fsx closure")>]
+    member public this.``Fsx.ExactlyOneError.ScriptClosure.TransitiveLoad6``() =  
+        use _guard = this.UsingNewVS()
+        let solution = this.CreateSolution()
+        let project = CreateProject(solution,"testproject")    
+        let file1fsi = AddFileFromText(project,"File1.fsi",
+                                      ["namespace Namespace"
+                                       "type Foo ="
+                                       "  class"
+                                       "    static member Property : int" // Not exposing 'HiddenProperty'
+                                       "  end"
+                                       ])            
+        let file1 = AddFileFromText(project,"File1.fs",
+                                    ["namespace Namespace"
+                                     "type Foo = "
+                                     "     static member public HiddenProperty = 0"
+                                     "     static member public Property = 0"
+                                     ])    
+
+        let script1 = AddFileFromText(project,"Script1.fsx",
+                                      ["#load \"File1.fsi\""
+                                       "#load \"File1.fs\""
+                                       ])     
+        let script2 = AddFileFromText(project,"Script2.fsx",
+                                      ["#load \"Script1.fsx\""
+                                       "Namespace.Foo.HiddenProperty" 
+                                       ])    
+        let script2 = OpenFile(project,"Script2.fsx")   
+        AssertExactlyOneErrorSeenContaining(project, "HiddenProperty") 
+        
+    // #load of .fsi is respected when dispersed between two #load levels
+    [<Test>]
+    [<Category("fsx closure")>]
+    member public this.``Fsx.ExactlyOneError.ScriptClosure.TransitiveLoad7``() =  
+        use _guard = this.UsingNewVS()
+        let solution = this.CreateSolution()
+        let project = CreateProject(solution,"testproject")    
+        let file1fsi = AddFileFromText(project,"File1.fsi",
+                                      ["namespace Namespace"
+                                       "type Foo ="
+                                       "  class"
+                                       "    static member Property : int" // Not exposing 'HiddenProperty'
+                                       "  end"
+                                       ])            
+        let file1 = AddFileFromText(project,"File1.fs",
+                                    ["namespace Namespace"
+                                     "type Foo = "
+                                     "     static member public HiddenProperty = 0"
+                                     "     static member public Property = 0"
+                                     ])    
+
+        let script1 = AddFileFromText(project,"Script1.fsx",
+                                      ["#load \"File1.fsi\""
+                                       ])     
+        let script2 = AddFileFromText(project,"Script2.fsx",
+                                      ["#load \"Script1.fsx\""
+                                       "#load \"File1.fs\""
+                                       "Namespace.Foo.HiddenProperty" 
+                                       ])    
+        let script2 = OpenFile(project,"Script2.fsx")   
+        AssertExactlyOneErrorSeenContaining(project, "HiddenProperty")    
+        
+    // #load of .fsi is respected when dispersed between two #load levels (the other way)
+    [<Test>]
+    [<Category("fsx closure")>]
+    member public this.``Fsx.ExactlyOneError.ScriptClosure.TransitiveLoad8``() =  
+        use _guard = this.UsingNewVS()
+        let solution = this.CreateSolution()
+        let project = CreateProject(solution,"testproject")    
+        let file1fsi = AddFileFromText(project,"File1.fsi",
+                                      ["namespace Namespace"
+                                       "type Foo ="
+                                       "  class"
+                                       "    static member Property : int" // Not exposing 'HiddenProperty'
+                                       "  end"
+                                       ])            
+        let file1 = AddFileFromText(project,"File1.fs",
+                                    ["namespace Namespace"
+                                     "type Foo = "
+                                     "     static member public HiddenProperty = 0"
+                                     "     static member public Property = 0"
+                                     ])    
+
+        let script1 = AddFileFromText(project,"Script1.fsx",
+                                      ["#load \"File1.fs\""
+                                       ])     
+        let script2 = AddFileFromText(project,"Script2.fsx",
+                                      ["#load \"File1.fsi\""
+                                       "#load \"Script1.fsx\""
+                                       "Namespace.Foo.HiddenProperty" 
+                                       ])    
+        let script2 = OpenFile(project,"Script2.fsx")   
+        AssertExactlyOneErrorSeenContaining(project, "HiddenProperty")   
+        
+    // Bug seen during development: A #load in an .fs would be followed.
+    [<Test>]
+    [<Category("fsx closure")>]
+    member public this.``Fsx.ExactlyOneError.ScriptClosure.TransitiveLoad15``() =  
+        use _guard = this.UsingNewVS()
+        let solution = this.CreateSolution()
+        let project = CreateProject(solution,"testproject")    
+        let file2 = AddFileFromText(project,"File2.fs",
+                                      ["namespace Namespace"
+                                       "type Type() ="
+                                       "    static member Property = 0"
+                                       ])  
+        let file1 = AddFileFromText(project,"File1.fs",
+                                      ["#load \"File2.fs\""  // This is not allowed but it was working anyway.
+                                       "namespace File2Namespace"
+                                       ])                                              
+        let script1 = AddFileFromText(project,"Script1.fsx",
+                                      ["#load \"File1.fs\""
+                                       "Namespace.Type.Property"
+                                       ])                                                   
+
+        let script1 = OpenFile(project,"Script1.fsx")   
+        TakeCoffeeBreak(this.VS)
+        AssertExactlyOneErrorSeenContaining(project, "Namespace")  
+
+    [<Test>]
+    member public this.``Fsx.Bug4311HoverOverReferenceInFirstLine``() =
+        let fileContent = """#r "PresentationFramework.dll"
+                             
+                             #r "PresentationCore.dll" """
+        let marker = "#r \"PresentationFrame"
+        this.AssertQuickInfoContainsAtEndOfMarkerInFsxFile fileContent marker "PresentationFramework.dll"
+        this.AssertQuickInfoNotContainsAtEndOfMarkerInFsxFile fileContent marker "multiple results"
+
+    [<Test>]
+    member public this.``Fsx.QuickInfo.Bug4979``() =
+        let code = 
+                ["System.ConsoleModifiers.Shift |> ignore "
+                 "(3).ToString().Length |> ignore "]
+        let (project, file) = createSingleFileFsxFromLines code
+        MoveCursorToEndOfMarker(file, "System.ConsoleModifiers.Sh")
+        let tooltip = GetQuickInfoAtCursor file
+        AssertContains(tooltip, @"[Signature:F:System.ConsoleModifiers.Shift]") // A message from the mock IdealDocumentationProvider
+        AssertContains(tooltip, @"[Filename:") 
+        AssertContains(tooltip, @"mscorlib.dll]") // The assembly we expect the documentation to get taken from     
+        
+        MoveCursorToEndOfMarker(file, "(3).ToString().Len")
+        let tooltip = GetQuickInfoAtCursor file
+        AssertContains(tooltip, @"[Signature:P:System.String.Length]") // A message from the mock IdealDocumentationProvider
+        AssertContains(tooltip, @"[Filename:") 
+        AssertContains(tooltip, @"mscorlib.dll]") // The assembly we expect the documentation to get taken from  
+
+    // Especially under 4.0 we need #r of .NET framework assemblies to resolve from like,
+    //
+    //      %program files%\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0
+    //
+    // because this is where the the .XML files are.
+    //
+    // When executing scripts, however, we need to _not_ resolve from these directories because
+    // they may be metadata-only assemblies.
+    //
+    // "Reference Assemblies" was only introduced in 3.5sp1, so not all 2.0 F# boxes will have it, so only run on 4.0
+    [<Test>]
+    member public this.``Fsx.Bug5073``() =
+        let fileContent = """#r "System" """
+        let marker = "#r \"System"
+        this.AssertQuickInfoContainsAtEndOfMarkerInFsxFile fileContent marker @"Reference Assemblies\Microsoft"
+        this.AssertQuickInfoContainsAtEndOfMarkerInFsxFile fileContent marker ".NET Framework"
+
+    /// FEATURE: Hovering over a resolved #r file will show a data tip with the fully qualified path to that file.
+    [<Test>]
+    member public this.``Fsx.HashR_QuickInfo.ShowFilenameOfResolvedAssembly``() =
+        this.AssertQuickInfoContainsAtEndOfMarkerInFsxFile
+            """#r "System.Transactions" """ // Pick anything that isn't in the standard set of assemblies.
+            "#r \"System.Tra" "System.Transactions.dll"
+
+    [<Test>]
+    member public this.``Fsx.HashR_QuickInfo.BugDefaultReferenceFileIsAlsoResolved``() =
+        this.AssertQuickInfoContainsAtEndOfMarkerInFsxFile
+            """#r "System" """  // 'System' is in the default set. Make sure we can still resolve it.
+            "#r \"Syst" "System.dll"
+        
+    [<Test>]
+    [<Category("fsx closure")>]
+    member public this.``Fsx.HashR_QuickInfo.DoubleReference``() =
+        let fileContent = """#r "System" // Mark1
+                             #r "System" // Mark2 """   // The same reference repeated twice. 
+        this.AssertQuickInfoContainsAtStartOfMarkerInFsxFile fileContent "tem\" // Mark1" "System.dll"
+        this.AssertQuickInfoContainsAtStartOfMarkerInFsxFile fileContent "tem\" // Mark2" "System.dll"
+        
+    [<Test>]
+    [<Category("fsx closure")>]
+    member public this.``Fsx.HashR_QuickInfo.ResolveFromGAC``() = 
+        this.AssertQuickInfoContainsAtEndOfMarkerInFsxFile
+            """#r "mscorcfg" """        // 'mscorcfg' is loaded from the GAC _and_ it is available on XP and above.
+            "#r \"mscor" "Global Assembly Cache"
+
+    [<Test>]
+    [<Category("fsx closure")>]
+    member public this.``Fsx.HashR_QuickInfo.ResolveFromAssemblyFoldersEx``() =  
+        let fileContent = """#r "Microsoft.TeamFoundation.Diff" """     // 'Microsoft.TeamFoundation.Diff' is located via AssemblyFoldersEx
+        let marker = "#r \"Microsoft.Tea"
+        this.AssertQuickInfoContainsAtEndOfMarkerInFsxFile fileContent marker "Found by AssemblyFoldersEx registry key"
+        this.AssertQuickInfoContainsAtEndOfMarkerInFsxFile fileContent marker "Microsoft.TeamFoundation.Diff"
+
+    [<Test>]
+    [<Category("fsx closure")>]
+    member public this.``Fsx.HashR_QuickInfo.ResolveFromAssemblyFolders``() =
+        let fileContent = """#r "Microsoft.SqlServer.SString" """       // Can be any assembly that is in AssemblyFolders but not AssemblyFoldersEx
+        let marker = "#r \"Microsoft.SqlSe"
+        this.AssertQuickInfoContainsAtEndOfMarkerInFsxFile fileContent marker "Microsoft.SqlServer.SString.dll"
+        this.AssertQuickInfoContainsAtEndOfMarkerInFsxFile fileContent marker "Found by AssemblyFolders registry key"
+        
+    [<Test>]
+    [<Category("fsx closure")>]
+    member public this.``Fsx.HashR_QuickInfo.ResolveFromFullyQualifiedPath``() = 
+        let fullyqualifiepathtoddll = System.IO.Path.Combine( System.Runtime.InteropServices.RuntimeEnvironment.GetRuntimeDirectory(), "System.configuration.dll" ) // Can be any fully qualified path to an assembly
+        let expectedtooltip = System.Reflection.Assembly.ReflectionOnlyLoadFrom(fullyqualifiepathtoddll).FullName
+        let fileContent = "#r @\"" + fullyqualifiepathtoddll + "\""
+        let marker = "#r @\"" + fullyqualifiepathtoddll.Substring(0,fullyqualifiepathtoddll.Length/2)       // somewhere in the middle of the string
+        this.AssertQuickInfoContainsAtEndOfMarkerInFsxFile fileContent marker expectedtooltip
+        this.AssertQuickInfoNotContainsAtEndOfMarkerInFsxFile fileContent marker ".dll"
+
+    [<Test>]
+    member public this.``Fsx.InvalidHashReference.ShouldBeASquiggle.Bug3012``() =  
+        let code = 
+            ["#light"
+             "#r \"Bar.dll\""]
+        let (project, file) = createSingleFileFsxFromLines code
+        MoveCursorToEndOfMarker(file,"#r \"Ba") 
+        let squiggle = GetSquiggleAtCursor(file)
+        TakeCoffeeBreak(this.VS)
+        Assert.IsTrue(snd squiggle.Value |> fun str -> str.Contains("Bar.dll"))
+
+    // Bug seen during development: The unresolved reference error would x-ray through to the root.
+    [<Test>]
+    [<Category("fsx closure")>]
+    member public this.``Fsx.ScriptClosure.TransitiveLoad14``() =  
+        use _guard = this.UsingNewVS()
+        let solution = this.CreateSolution()
+        let project = CreateProject(solution,"testproject")    
+        let script2 = AddFileFromText(project,"Script2.fsx",
+                                      ["#load \"Script1.fsx\""
+                                       "#r \"NonExisting\""
+                                       ])      
+        let script1 = AddFileFromText(project,"Script1.fsx",
+                                      ["#load \"Script2.fsx\""
+                                       "#r \"System\""
+                                       ])                                                   
+
+        let script1 = OpenFile(project,"Script1.fsx")   
+        TakeCoffeeBreak(this.VS)      
+        MoveCursorToEndOfMarker(script1,"#r \"Sys") 
+        AssertEqual(None,GetSquiggleAtCursor(script1))
+    
+    member private this.TestFsxHashDirectivesAreErrors(mark : string, expectedStr : string) = 
+        let code = 
+                                    ["#light"
+                                     "#r \"JoeBob\""
+                                     "#I \".\""
+                                     "#load \"Dooby\""
+                                     ]
+        let (_, _, file) = this.CreateSingleFileProject(code)
+        MoveCursorToEndOfMarker(file,mark) 
+        let ans = GetSquiggleAtCursor(file)
+        match ans with
+        | Some(sev,msg) -> 
+            AssertEqual(Microsoft.VisualStudio.FSharp.LanguageService.Severity.Error,sev)
+            AssertContains(msg,expectedStr)
+        | _ -> Assert.Fail() 
+
+    /// FEATURE: #r, #I, #load are all errors when running under the language service
+    [<Test>]
+    member public this.``Fsx.HashDirectivesAreErrors.InNonScriptFiles.Case1``() =  
+        this.TestFsxHashDirectivesAreErrors("#r \"Joe","#r")
+     
+    [<Test>]
+    member public this.``Fsx.HashDirectivesAreErrors.InNonScriptFiles.Case2``() =  
+        this.TestFsxHashDirectivesAreErrors("#I \"","#I")      
+        
+    [<Test>]
+    member public this.``Fsx.HashDirectivesAreErrors.InNonScriptFiles.Case3``() =  
+        this.TestFsxHashDirectivesAreErrors("#load \"Doo","may only be used in F# script files")      
+
+    /// FEATURE: #reference against a non-assembly .EXE gives a reasonable error message
+    //[<Test>]
+    member public this.``Fsx.HashReferenceAgainstNonAssemblyExe``() = 
+        let windows = System.Environment.GetEnvironmentVariable("windir")
+        let code =
+                                    ["#light"
+                                     sprintf "#reference @\"%s\"" (Path.Combine(windows,"notepad.exe"))
+                                     "    let x = 1"]
+        let (_, file) = createSingleFileFsxFromLines code
+        
+        MoveCursorToEndOfMarker(file,"#refe")
+        let ans = GetSquiggleAtCursor(file)
+        AssertSquiggleIsErrorContaining(ans, "was not found or is invalid")
+
+    (* ---------------------------------------------------------------------------------- *)
+
+     // FEATURE: A #loaded file is squiggled with an error if there are errors in that file.
+    [<Test>]
+    [<Category("fsx closure")>]
+    member public this.``Fsx.HashLoadedFileWithErrors.Bug3149``() =
+        use _guard = this.UsingNewVS()
+        let solution = this.CreateSolution()
+        let project = CreateProject(solution,"testproject")
+        
+        let file1 = AddFileFromText(project,"File1.fs", 
+                                    ["#light"
+                                     "module File1" 
+                                     "DogChow" // <-- error
+                                    ])
+
+        let file2 = AddFileFromText(project,"File2.fsx",
+                                    ["#light"
+                                     "#load @\"File1.fs\""
+                                     ])
+        let file2 = OpenFile(project,"File2.fsx")
+        
+        MoveCursorToEndOfMarker(file2,"#load @\"Fi")
+        TakeCoffeeBreak(this.VS)        
+        let ans = GetSquiggleAtCursor(file2)    
+        AssertSquiggleIsErrorContaining(ans, "DogChow")      
+        
+        
+     // FEATURE: A #loaded file is squiggled with a warning if there are warning that file.
+    [<Test>]
+    [<Category("fsx closure")>]
+    member public this.``Fsx.HashLoadedFileWithWarnings.Bug3149``() =
+        use _guard = this.UsingNewVS()
+        let solution = this.CreateSolution()
+        let project = CreateProject(solution,"testproject")
+        
+        let file1 = AddFileFromText(project,"File1.fs", 
+                                    ["module File1Module"
+                                     "type WarningHere<'a> = static member X() = 0"
+                                     "let y = WarningHere.X"
+                                    ])
+
+        let file2 = AddFileFromText(project,"File2.fsx",
+                                    ["#light"
+                                     "#load @\"File1.fs\""
+                                     ])
+        let file2 = OpenFile(project,"File2.fsx")
+        
+        MoveCursorToEndOfMarker(file2,"#load @\"Fi")
+        let ans = GetSquiggleAtCursor(file2)
+        AssertSquiggleIsWarningContaining(ans, "WarningHere")  
+
+     // Bug: #load should report the first error message from a file
+    [<Test>]
+    [<Category("fsx closure")>]
+    member public this.``Fsx.HashLoadedFileWithErrors.Bug3652``() =
+        use _guard = this.UsingNewVS()
+        let solution = this.CreateSolution()
+        let project = CreateProject(solution,"testproject")
+        
+        let file1 = AddFileFromText(project,"File1.fs", 
+                                    [ "#light"
+                                      "module File1" 
+                                      "let a = 1 + \"\""
+                                      "let c = new obj()"
+                                      "let b = c.foo()"
+                                    ])
+        let file2 = AddFileFromText(project,"File2.fsx",
+                                    ["#light"
+                                     "#load @\"File1.fs\""
+                                     ])
+        let file2 = OpenFile(project,"File2.fsx")
+       
+        MoveCursorToEndOfMarker(file2,"#load @\"Fi")
+        let ans = GetSquiggleAtCursor(file2)
+        AssertSquiggleIsErrorContaining(ans, "'string'")
+        AssertSquiggleIsErrorContaining(ans, "'int'")
+        AssertSquiggleIsErrorNotContaining(ans, "foo")
+
+    // In this bug the .fsx project directory was wrong so it couldn't reference a relative file.
+    [<Test>]
+    member public this.``Fsx.ScriptCanReferenceBinDirectoryOutput.Bug3151``() =
+        use _guard = this.UsingNewVS()
+        let stopWatch = new System.Diagnostics.Stopwatch()
+        let ResetStopWatch() = stopWatch.Reset(); stopWatch.Start()
+        let time1 op a message = 
+            ResetStopWatch()
+            let result = op a
+            printf "%s %d ms\n" message stopWatch.ElapsedMilliseconds
+            result
+        let solution = this.CreateSolution()
+        let project = CreateProject(solution,"testproject")
+        let file1 = AddFileFromText(project,"File1.fs", ["#light"])
+        let projectOutput = time1 Build project "Time to build project"
+        printfn "Output of building project was %s" projectOutput.ExecutableOutput
+        printfn "Project directory is %s" (ProjectDirectory project)
+        
+        let file2 = AddFileFromText(project,"File2.fsx",
+                                    ["#light"
+                                     "#reference @\"bin\\Debug\\testproject.exe\""
+                                     ])
+        let file2 = OpenFile(project,"File2.fsx")
+        
+        MoveCursorToEndOfMarker(file2,"#reference @\"bin\\De")
+        let ans = GetSquiggleAtCursor(file2)
+        AssertNoSquiggle(ans)
+
+               
+
+    /// In this bug, multiple references to mscorlib .dll were causing problem in load closure
+    [<Test>]
+    [<Category("fsx closure")>]
+    member public this.``Fsx.BugAllowExplicitReferenceToMsCorlib``() =  
+        let code =
+                                    ["#r \"mscorlib\""
+                                     "fsi."
+                                     ]
+        let (_, file) = createSingleFileFsxFromLines code
+        MoveCursorToEndOfMarker(file,"fsi.")
+        TakeCoffeeBreak(this.VS)
+        let completions = AutoCompleteAtCursor file
+        AssertCompListContains(completions,"CommandLineArgs")        
+        
+    /// FEATURE: There is a global fsi module that should be in scope for script files.        
+    [<Test>]
+    [<Category("fsx closure")>]
+    member public this.``Fsx.Bug2530FsiObject``() =  
+        let code = 
+                                    ["#light"
+                                     "fsi."
+                                     ]
+        let (_, file) = createSingleFileFsxFromLines code
+        MoveCursorToEndOfMarker(file,"fsi.")
+        TakeCoffeeBreak(this.VS)
+        let completions = AutoCompleteAtCursor file
+        AssertCompListContains(completions,"CommandLineArgs")
+  
+    // Ensure that the script closure algorithm gets the right order of hash directives
+    [<Test>]
+    [<Category("fsx closure")>]
+    member public this.``Fsx.ScriptClosure.SurfaceOrderOfHashes``() =  
+        let code = 
+                                    ["#r \"System.Runtime.Remoting\""
+                                     "#r \"System.Transactions\""
+                                     "#load \"Load1.fs\""
+                                     "#load \"Load2.fsx\""
+                                     ]
+        let (project, file) = createSingleFileFsxFromLines code
+        let projectFolder = ProjectDirectory(project)
+        let fas = GetCheckOptionsOfScript(file)
+        AssertArrayContainsPartialMatchOf(fas.ProjectOptions, "--noframework")
+        AssertArrayContainsPartialMatchOf(fas.ProjectOptions, "System.Runtime.Remoting.dll")
+        AssertArrayContainsPartialMatchOf(fas.ProjectOptions, "System.Transactions.dll")
+        AssertArrayContainsPartialMatchOf(fas.ProjectOptions, "FSharp.Compiler.Interactive.Settings.dll")
+        Assert.AreEqual(Path.Combine(projectFolder,"File1.fsx"), fas.ProjectFileNames.[0])
+        Assert.AreEqual(1, fas.ProjectFileNames.Length)
+
+#if OPEN_BUILD
+#else
+
+    /// FEATURE: #reference against a strong name should work.
+    [<Test>]
+    member public this.``Fsx.HashReferenceAgainstStrongName``() = 
+        let code =
+                                            ["#light"
+#if FX_ATLEAST_40                                            
+                                             sprintf "#reference \"System.Core, Version=%s, Culture=neutral, PublicKeyToken=b77a5c561934e089\"" Microsoft.BuildSettings.Version.OfAssembly
+#else
+                                             "#reference \"System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\""
+#endif                                             
+                                             "open System."]
+        let (_, file) = createSingleFileFsxFromLines code
+        MoveCursorToEndOfMarker(file,"open System.") 
+        let completions = AutoCompleteAtCursor file
+        AssertCompListContains(completions,"Linq")   
+#endif
+
+    /// Try out some bogus file names in #r, #I and #load.
+    [<Test>]
+    member public this.``Fsx.InvalidMetaCommandFilenames``() =
+        let code = 
+                                    [
+                                     "#r @\"\""
+                                     "#load @\"\""
+                                     "#I @\"\""
+                                     "#r @\"*\""
+                                     "#load @\"*\""
+                                     "#I @\"*\""
+                                     "#r @\"?\""
+                                     "#load @\"?\""
+                                     "#I @\"?\""
+                                     """#r @"C:\path\does\not\exist.dll"  """
+                                    ]
+        let (_, file) = createSingleFileFsxFromLines code
+        TakeCoffeeBreak(this.VS) // This used to assert
+
+    /// FEATURE: .fsx files have INTERACTIVE #defined
+    [<Test>]
+    member public this.``Fsx.INTERACTIVEIsDefinedInFsxFiles``() =
+        let code =
+                                    [
+                                     "#if INTERACTIVE"
+                                     "let xyz = 1"
+                                     "#endif"
+                                    ]
+        let (_, file) = createSingleFileFsxFromLines code
+        MoveCursorToEndOfMarker(file,"let xy")
+        AssertEqual(TokenType.Identifier ,GetTokenTypeAtCursor(file))  
+
+    // Ensure that basic compile of an .fsx works        
+    [<Test>]
+    [<Category("fsx closure")>]
+    [<Category("fsx compile")>]
+    member public this.``Fsx.CompileFsx_1``() =
+        use _guard = this.UsingNewVS()
+        let solution = this.CreateSolution()
+        let project = CreateProject(solution,"testproject")
+        
+        let file1 = AddFileFromTextEx(project,"Script.fsx","Script.fsx",BuildAction.Compile,
+                                      ["printfn \"Hello world\""])
+        let build = time1 Build project "Time to build project"
+        Assert.IsTrue(build.BuildSucceeded, "Expected build to succeed")
+        ShowErrors(project)
+        
+
+    // Compile a script which #loads a source file. The build can't succeed without the loaded file.      
+    [<Test>]
+    [<Category("fsx closure")>]
+    [<Category("fsx compile")>]
+    member public this.``Fsx.CompileFsx_2``() =
+        use _guard = this.UsingNewVS()
+        let solution = this.CreateSolution()
+        let project = CreateProject(solution,"testproject")
+        let fs = AddFileFromTextEx(project,"File.fs","File.fs",BuildAction.Compile,
+                                      ["namespace Namespace"
+                                       "module Module ="
+                                       "  let Value = 1"
+                                      ])
+        let fsx = AddFileFromTextEx(project,"Script.fsx","Script.fsx",BuildAction.Compile,
+                                      ["#load \"File.fs\""
+                                       "printfn \"%d\" Namespace.Module.Value"])
+        let build = time1 Build project "Time to build project"
+        if SupportsOutputWindowPane(this.VS) then 
+            let lines = GetOutputWindowPaneLines(this.VS)
+            for line in lines do printfn "%s" line
+            ()
+        Assert.IsTrue(build.BuildSucceeded, "Expected build to succeed")
+        
+    // Compile a script which #loads a source file. The build can't succeed without 
+    [<Test>]
+    [<Category("fsx closure")>]
+    [<Category("fsx compile")>]
+    member public this.``Fsx.CompileFsx_3``() =
+        use _guard = this.UsingNewVS()
+        let solution = this.CreateSolution()
+        let project = CreateProject(solution,"testproject")
+        let fs = AddFileFromTextEx(project,"File.fs","File.fs",BuildAction.None,
+                                      ["namespace Namespace"
+                                       "module Module ="
+                                       "  let Value = 1"
+                                      ])
+        let fsx = AddFileFromTextEx(project,"Script.fsx","Script.fsx",BuildAction.Compile,
+                                      ["#load \"File.fs\""
+                                       "printfn \"%d\" Namespace.Module.Value"])
+        let build = time1 Build project "Time to build project" 
+        if SupportsOutputWindowPane(this.VS) then 
+            let lines = GetOutputWindowPaneLines(this.VS)
+            for line in lines do printfn "%s" line
+            ()
+        Assert.IsTrue(build.BuildSucceeded, "Expected build to succeed")        
+        
+    // Must be explicitly referenced by compile.
+    [<Test>]
+    [<Category("fsx closure")>]
+    [<Category("fsx compile")>]
+    member public this.``Fsx.CompileFsx_Bug5416_1``() =
+        use _guard = this.UsingNewVS()
+        let solution = this.CreateSolution()
+        let project = CreateProject(solution,"testproject")
+        let fsx = AddFileFromTextEx(project,"Script.fsx","Script.fsx",BuildAction.Compile,
+                                      ["let x = fsi.CommandLineArgs"])
+        let build = time1 Build project "Time to build project" 
+        if SupportsOutputWindowPane(this.VS) then 
+            let lines = GetOutputWindowPaneLines(this.VS)
+            for line in lines do printfn "%s" line
+            ()
+        Assert.IsTrue(not(build.BuildSucceeded), "Expected build to fail")    
+        
+    // Must be explicitly referenced by compile.
+    [<Test>]
+    [<Category("fsx closure")>]
+    [<Category("fsx compile")>]
+    member public this.``Fsx.CompileFsx_Bug5416_2``() =
+        use _guard = this.UsingNewVS()
+        let solution = this.CreateSolution()
+        let project = CreateProject(solution,"testproject")
+#if FX_ATLEAST_45
+        PlaceIntoProjectFileBeforeImport
+            (project, @"
+                <ItemGroup>
+                    <!-- Subtle: You need this reference to compile but not to get language service -->
+                    <Reference Include=""FSharp.Compiler.Interactive.Settings, Version=4.3.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"">
+                        <SpecificVersion>True</SpecificVersion>
+                    </Reference>
+                    <Reference Include=""FSharp.Compiler, Version=4.3.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"">
+                        <SpecificVersion>True</SpecificVersion>
+                    </Reference>
+                </ItemGroup>")
+#else
+        PlaceIntoProjectFileBeforeImport
+            (project, @"
+                <ItemGroup>
+                    <!-- Subtle: You need this reference to compile but not to get language service -->
+                    <Reference Include=""FSharp.Compiler.Interactive.Settings, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"">
+                        <SpecificVersion>True</SpecificVersion>
+                    </Reference>
+                    <Reference Include=""FSharp.Compiler, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"">
+                        <SpecificVersion>True</SpecificVersion>
+                    </Reference>
+                </ItemGroup>")
+#endif
+        let fsx = AddFileFromTextEx(project,"Script.fsx","Script.fsx",BuildAction.Compile,
+                                      ["let x = fsi.CommandLineArgs"])
+        let build = time1 Build project "Time to build project" 
+        if SupportsOutputWindowPane(this.VS) then 
+            let lines = GetOutputWindowPaneLines(this.VS)
+            for line in lines do printfn "%s" line
+            ()
+        if not(SupportsOutputWindowPane(this.VS)) then  
+            Assert.IsTrue(build.BuildSucceeded, "Expected build to succeed")                
+        
+        
+    // Ensure that #load order is preserved when #loading multiple files. 
+    [<Test>]
+    [<Category("fsx closure")>]
+    [<Category("fsx compile")>]
+    member public this.``Fsx.CompileFsx_5``() =
+        use _guard = this.UsingNewVS()
+        let solution = this.CreateSolution()
+        let project = CreateProject(solution,"testproject")
+        let fs1 = AddFileFromTextEx(project,"File1.fs","File1.fs",BuildAction.None,
+                                      ["namespace Namespace"
+                                       "module Module1 ="
+                                       "  let Value = 1"
+                                      ])
+        let fs2 = AddFileFromTextEx(project,"File2.fs","File2.fs",BuildAction.None,
+                                      ["namespace Namespace"
+                                       "module Module2 ="
+                                       "  let Value = Module1.Value"
+                                      ])                                      
+        let fsx = AddFileFromTextEx(project,"Script.fsx","Script.fsx",BuildAction.Compile,
+                                      [
+                                       "#load \"File1.fs\""
+                                       "#load \"File2.fs\""
+                                       "printfn \"%d\" Namespace.Module2.Value"])
+        let build = time1 Build project "Time to build project" 
+        if SupportsOutputWindowPane(this.VS) then 
+            let lines = GetOutputWindowPaneLines(this.VS)
+            for line in lines do printfn "%s" line
+            ()
+        Assert.IsTrue(build.BuildSucceeded, "Expected build to succeed")          
+        
+    // If an fs file is explicitly passed in to the compiler and also #loaded then 
+    // the command-line order is respected rather than the #load order
+    [<Test>]
+    [<Category("fsx closure")>]
+    [<Category("fsx compile")>]
+    member public this.``Fsx.CompileFsx_6``() =
+        use _guard = this.UsingNewVS()
+        let solution = this.CreateSolution()
+        let project = CreateProject(solution,"testproject")
+        let fs1 = AddFileFromTextEx(project,"File1.fs","File1.fs",BuildAction.Compile,
+                                      ["namespace Namespace"
+                                       "module Module1 ="
+                                       "  let Value = 1"
+                                      ])
+        let fs2 = AddFileFromTextEx(project,"File2.fs","File2.fs",BuildAction.Compile,
+                                      ["namespace Namespace"
+                                       "module Module2 ="
+                                       "  let Value = Module1.Value"
+                                      ])                                      
+        let fsx = AddFileFromTextEx(project,"Script.fsx","Script.fsx",BuildAction.Compile,
+                                      [
+                                       "#load \"File2.fs\"" // Wrong order
+                                       "#load \"File1.fs\""
+                                       "printfn \"%d\" Namespace.Module2.Value"])
+        let build = time1 Build project "Time to build project" 
+        if SupportsOutputWindowPane(this.VS) then 
+            let lines = GetOutputWindowPaneLines(this.VS)
+            for line in lines do printfn "%s" line
+            ()
+        Assert.IsTrue(build.BuildSucceeded, "Expected build to succeed") 
+
+        
+        
+    // If a #loaded file does not exist, there should be an error
+    [<Test>]
+    [<Category("fsx closure")>]
+    [<Category("fsx compile")>]
+    member public this.``Fsx.CompileFsx_7``() =
+        use _guard = this.UsingNewVS()
+        let solution = this.CreateSolution()
+        let project = CreateProject(solution,"testproject")
+        let fsx = AddFileFromTextEx(project,"Script.fsx","Script.fsx",BuildAction.Compile,
+                                      [
+                                       "#load \"NonexistentFile.fs\""
+                                       ])
+        let build = time1 Build project "Time to build project" 
+        if SupportsOutputWindowPane(this.VS) then 
+            let lines = GetOutputWindowPaneLines(this.VS)
+            for line in lines do printfn "%s" line
+            AssertListContainsInOrder(lines, ["error FS0079: Could not load file"; "NonexistentFile.fs"; "because it does not exist or is inaccessible"])            
+            
+        Assert.IsTrue(not(build.BuildSucceeded), "Expected build to fail")       
+        
+        
+    // #r references should be respected.
+    [<Test>]
+    [<Category("fsx closure")>]
+    [<Category("fsx compile")>]
+    member public this.``Fsx.CompileFsx_8``() =
+        use _guard = this.UsingNewVS()
+        let solution = this.CreateSolution()
+        let project = CreateProject(solution,"testproject")
+        let fsx = AddFileFromTextEx(project,"Script.fsx","Script.fsx",BuildAction.Compile,
+                                      [
+                                       "#r \"System.Messaging\""
+                                       "let a = new System.Messaging.AccessControlEntry()"
+                                       ])
+        let build = time1 Build project "Time to build project" 
+        if SupportsOutputWindowPane(this.VS) then 
+            let lines = GetOutputWindowPaneLines(this.VS)
+            for line in lines do printfn "%s" line
+            
+        Assert.IsTrue(build.BuildSucceeded, "Expected build to succeed")          
+        
+        
+    // Missing script file should be a reasonable failure, not a callstack.
+    [<Test>]
+    [<Category("fsx closure")>]
+    [<Category("fsx compile")>]
+    member public this.``Fsx.CompileFsx_Bug5414``() =
+        use _guard = this.UsingNewVS()
+        let solution = this.CreateSolution()
+        let project = CreateProject(solution,"testproject")
+        let fsx = AddFileFromTextEx(project,"Script.fsx","Script.fsx",BuildAction.Compile,[])
+        DeleteFileFromDisk(this.VS, fsx) 
+        
+        let build = Build project
+        if SupportsOutputWindowPane(this.VS) then 
+            let lines = GetOutputWindowPaneLines(this.VS)
+            AssertListContainsInOrder(lines, 
+                                      ["Could not find file "
+                                       "Script.fsx"])           
+            for line in lines do 
+                printfn "%s" line
+                AssertNotContains(line,"error MSB") // Microsoft.FSharp.targets(135,9): error MSB6006: "fsc.exe" exited with code -532462766.
+
+        Assert.IsTrue(not(build.BuildSucceeded), "Expected build to fail")                                  
+        
+        
+    /// There was a problem in which synthetic tokens like #load were causing asserts
+    [<Test>]
+    [<Category("PerfCheck")>]
+    member public this.``Fsx.SyntheticTokens``() =     
+        Helper.ExhaustivelyScrutinize(
+            this.TestRunner,
+              ["#light"
+               "#r \"\""
+               "#reference \"\""
+               "#load \"\""
+               "#line 52"
+               "#nowarn 72"]        
+            )
+                                 
+    /// There was a problem where an unclosed reference picked up the text of the reference on the next line.
+    [<Test>]
+    member public this.``Fsx.ShouldBeAbleToReference30Assemblies.Bug2050``() =     
+        let code = 
+                                    ["#light"
+                                     "#r \"System.Core.dll\""
+                                     "open System."
+                                     ]
+        let (_, file) = createSingleFileFsxFromLines code
+        MoveCursorToEndOfMarker(file,"open System.") 
+        let completions = AutoCompleteAtCursor file
+        AssertCompListContains(completions,"Linq")
+
+    /// There was a problem where an unclosed reference picked up the text of the reference on the next line.
+    [<Test>]
+    member public this.``Fsx.UnclosedHashReference.Case1``() =     
+        Helper.ExhaustivelyScrutinize(
+            this.TestRunner,
+           ["#light"
+            "#reference \"" // Unclosed
+            "#reference \"Hello There\""]    
+            )
+    [<Test>]
+    member public this.``Fsx.UnclosedHashReference.Case2``() =     
+        Helper.ExhaustivelyScrutinize(
+            this.TestRunner,
+          ["#light"
+           "#r \"" // Unclosed
+           "# \"Hello There\""]                                            
+           )
+                                     
+    /// There was a problem where an unclosed reference picked up the text of the reference on the next line.
+    [<Test>]
+    member public this.``Fsx.UnclosedHashLoad``() =     
+        Helper.ExhaustivelyScrutinize(
+            this.TestRunner, 
+            [ "#light"
+              "#load \"" // Unclosed
+              "#load \"Hello There\""]
+            ) 
+        
+    //regression test for bug 2530
+    [<Test>]
+    [<Category("fsx moved from tao test")>]
+    member public this.``Fsx.IntellisenseForFSI``() =
+        let code = 
+                                      ["module Script"
+                                       "fsi(*MarkerFSI*)" 
+                                       ]
+        let (_, script1) = createSingleFileFsxFromLines code
+        TakeCoffeeBreak(this.VS)
+        let marker = "(*MarkerFSI*)"
+        let list = ["FormatProvider";"CommandLineArgs"]
+        let completions = DotCompletionAtStartOfMarker script1 marker
+        AssertCompListContainsAll(completions, list)
+
+    [<Test>]
+    [<Category("TypeProvider")>]
+    member public this.``TypeProvider.UnitsOfMeasure.SmokeTest1``() =
+        let code =
+                                    ["open Microsoft.FSharp.Data.UnitSystems.SI.UnitNames"
+                                     "let x : System.Nullable<decimal<kilogram / hertz^2>> = N1.T1.MethodWithTypesInvolvingUnitsOfMeasure(1.0<kilogram>)"
+                                     "let x2 : int = N1.T1().MethodWithErasedCodeUsingConditional()"
+                                     "let x3 : int = N1.T1().MethodWithErasedCodeUsingTypeAs()"
+                                     ]
+        let refs = 
+            [
+                System.IO.Path.Combine(System.Environment.CurrentDirectory, @"UnitTestsResources\MockTypeProviders\DummyProviderForLanguageServiceTesting.dll")
+            ]
+        let (_, project, file) = this.CreateSingleFileProject(code, references = refs)
+        TakeCoffeeBreak(this.VS)
+        AssertNoErrorsOrWarnings(project)
+
+    member public this.TypeProviderDisposalSmokeTest(clearing) =
+        use _guard = this.UsingNewVS()
+        let providerAssemblyName = System.IO.Path.Combine(System.Environment.CurrentDirectory, @"UnitTestsResources\MockTypeProviders\DummyProviderForLanguageServiceTesting.dll")
+        let providerAssembly = System.Reflection.Assembly.LoadFrom providerAssemblyName
+        Assert.IsNotNull(providerAssembly, "provider assembly should not be null")
+        let providerCounters = providerAssembly.GetType("DummyProviderForLanguageServiceTesting.GlobalCounters")
+        Assert.IsNotNull(providerCounters, "provider counters module should not be null")
+        let totalCreationsMeth = providerCounters.GetMethod("GetTotalCreations")
+        Assert.IsNotNull(totalCreationsMeth, "totalCreationsMeth should not be null")
+        let totalDisposalsMeth = providerCounters.GetMethod("GetTotalDisposals")
+        Assert.IsNotNull(totalDisposalsMeth, "totalDisposalsMeth should not be null")
+
+        let totalCreations() = totalCreationsMeth.Invoke(null, [| |]) :?> int
+        let totalDisposals() = totalDisposalsMeth.Invoke(null, [| |]) :?> int
+
+         
+        let startCreations = totalCreations()
+        let startDisposals = totalDisposals()
+        let countCreations() = totalCreations() - startCreations
+        let countDisposals() = totalDisposals() - startDisposals
+
+        Assert.IsTrue(startCreations >= startDisposals, "Check0")
+        for i in 1 .. 50 do 
+            let solution = this.CreateSolution()
+            let project = CreateProject(solution,"testproject" + string (i % 20))    
+            this.AddAssemblyReference(project, System.IO.Path.Combine(System.Environment.CurrentDirectory, @"UnitTestsResources\MockTypeProviders\DummyProviderForLanguageServiceTesting.dll"))
+            let fileName = sprintf "File%d.fs" i
+            let file1 = AddFileFromText(project,fileName, ["let x" + string i + " = N1.T1()" ])    
+            let file = OpenFile(project,fileName)
+            TakeCoffeeBreak(this.VS)
+            AssertNoErrorsOrWarnings project   // ...and not an error on the first line.
+            MoveCursorToEndOfMarker(file, "N1.T1")
+
+            // do some stuff to get declarations etc.
+            let tooltip = GetQuickInfoAtCursor file
+            AssertContains(tooltip, "T1")
+            ignore (GetF1KeywordAtCursor file)
+            let parmInfo = GetParameterInfoAtCursor file
+
+            let file1 = OpenFile(project,fileName)   
+
+            // The disposals should be at least one less 
+            Assert.IsTrue(countDisposals() < i, "Check1, countDisposals() < i, iteration " + string i)
+            Assert.IsTrue(countCreations() >= countDisposals(), "Check2, countCreations() >= countDisposals(), iteration " + string i)
+            Assert.IsTrue(countCreations() = i, "Check3, countCreations() = i, iteration " + string i)
+            if not clearing then 
+                // By default we hold 3 build incrementalBuilderCache entries and 5 typeCheckInfo entries, so if we're not clearing
+                // there should be some roots to project builds still present
+                if i >= 3 then 
+                    Assert.IsTrue(i >= countDisposals() + 3, "Check4a, i >= countDisposals() + 3, iteration " + string i + ", i = " + string i + ", countDisposals() = " + string (countDisposals()))
+
+            // If we forcefully clear out caches and force a collection, then we can say much stronger things...
+            if clearing then 
+                ClearLanguageServiceRootCachesAndCollectAndFinalizeAllTransients(this.VS)
+                Assert.IsTrue((i = countDisposals()), "Check4b, countCreations() = countDisposals(), iteration " + string i)
+        
+        Assert.IsTrue(countCreations() = 50, "Check5, at end, countCreations() = 50")
+        ClearLanguageServiceRootCachesAndCollectAndFinalizeAllTransients(this.VS)
+        Assert.IsTrue(countDisposals() = 50, "Check6b, at end, countDisposals() = 50 when clearing")
+
+    [<Test>]
+    [<Category("TypeProvider")>]
+    member public this.``TypeProvider.Disposal.SmokeTest1``() = this.TypeProviderDisposalSmokeTest(true)
+
+    [<Test>]
+    [<Category("TypeProvider")>]
+    member public this.``TypeProvider.Disposal.SmokeTest2``() = this.TypeProviderDisposalSmokeTest(false)
+
+//Allow the ScriptTests run under different context
+namespace UnitTests.Tests.LanguageService.Script
+open UnitTests.Tests.LanguageService
+open UnitTests.TestLib.LanguageService
+open UnitTests.TestLib.ProjectSystem
+open NUnit.Framework
+open Salsa.Salsa
+
+// context msbuild
+[<TestFixture>] 
+[<Category("LanguageService.MSBuild")>]
+type ``MSBuild`` = 
+   inherit ScriptTests
+   new() = { inherit ScriptTests(VsOpts = fst (Models.MSBuild())); }
+
+// Context project system
+[<TestFixture>] 
+[<Category("LanguageService.ProjectSystem")>]
+type ``ProjectSystem`` = 
+    inherit ScriptTests
+    new() = { inherit ScriptTests(VsOpts = LanguageServiceExtension.ProjectSystem); } 
+
diff --git a/vsintegration/src/unittests/Tests.LanguageService.Squiggles.fs b/vsintegration/src/unittests/Tests.LanguageService.Squiggles.fs
new file mode 100644
index 0000000..f283483
--- /dev/null
+++ b/vsintegration/src/unittests/Tests.LanguageService.Squiggles.fs
@@ -0,0 +1,1020 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+namespace UnitTests.Tests.LanguageService
+
+open System
+open System.IO
+open NUnit.Framework
+open Salsa.Salsa
+open Salsa.VsOpsUtils
+open UnitTests.TestLib.Salsa
+open UnitTests.TestLib.Utils
+open UnitTests.TestLib.LanguageService
+
+type SquiggleTests() as this= 
+    inherit LanguageServiceBaseTests()
+
+    #if FX_ATLEAST_45
+    let AA l = Some(System.IO.Path.Combine(System.IO.Path.GetTempPath(), ".NETFramework,Version=v4.0.AssemblyAttributes.fs")), l
+    let notAA l = None,l
+    #else
+    let AA l = None, l
+    let notAA l = None,l
+    #endif
+
+    let CheckSquiggles (fileContents : string) markers f = 
+        let (sln, proj, file) = this.CreateSingleFileProject(fileContents)        
+        TakeCoffeeBreak(this.VS)// Wait for the background compiler to catch up.
+
+        for marker in markers do
+            MoveCursorToStartOfMarker(file, marker)
+            let squiggles = GetSquigglesAtCursor(file)
+            f marker squiggles
+
+
+    /// Assert that there is no squiggle.
+    let AssertNoSquiggle(squiggleOption) = 
+        match squiggleOption with 
+        | None -> ()
+        | Some(severity,message) ->
+            Assert.Fail(sprintf "Expected no squiggle but got '%A' with message: %s" severity message)
+
+    /// Assert that a given squiggle is an Error (or warning) containing the given text        
+    let AssertSquiggleIsErrorContaining,AssertSquiggleIsWarningContaining, AssertSquiggleIsErrorNotContaining,AssertSquiggleIsWarningNotContaining =         
+        let AssertSquiggle expectedSeverity nameOfExpected nameOfNotExpected assertf (squiggleOption,containing) = 
+            match squiggleOption with
+            | None -> Assert.Fail("Expected a squiggle but none was seen.")
+            | Some(severity,message) ->
+                Assert.IsTrue((severity=expectedSeverity), sprintf "Expected %s but saw %s: %s" nameOfExpected nameOfNotExpected message)
+                assertf(message,containing)        
+        AssertSquiggle Microsoft.VisualStudio.FSharp.LanguageService.Severity.Error    "Error"    "Warning" AssertContains,
+        AssertSquiggle Microsoft.VisualStudio.FSharp.LanguageService.Severity.Warning  "Warning"  "Error"   AssertContains,
+        AssertSquiggle Microsoft.VisualStudio.FSharp.LanguageService.Severity.Error    "Error"    "Warning" AssertNotContains,
+        AssertSquiggle Microsoft.VisualStudio.FSharp.LanguageService.Severity.Warning  "Warning"  "Error"   AssertNotContains 
+
+    member private this.VerifyNoSquiggleAtStartOfMarker(fileContents : string, marker : string, ?addtlRefAssy : list<string>) = 
+        let (sln, proj, file) = this.CreateSingleFileProject(fileContents, ?references=addtlRefAssy)
+
+        MoveCursorToStartOfMarker(file, marker)        
+        TakeCoffeeBreak(this.VS)// Wait for the background compiler to catch up.
+        let squiggle = GetSquiggleAtCursor(file)
+        AssertEqual(None,squiggle)
+
+    member private this.VerifySquiggleAtStartOfMarker(fileContents : string, marker : string, expectedSquiggle : (Microsoft.VisualStudio.FSharp.LanguageService.Severity * string), ?addtlRefAssy : list<string>, ?thereShouldBeNoOtherSquigglesHere : bool) = 
+        let (sln, proj, file) = this.CreateSingleFileProject(fileContents, ?references=addtlRefAssy)
+        
+        TakeCoffeeBreak(this.VS)// Wait for the background compiler to catch up.
+
+        MoveCursorToStartOfMarker(file, marker)
+        let squiggles = GetSquigglesAtCursor(file)
+        if squiggles |> List.exists ((=) expectedSquiggle) then
+            ()  // ok, found it
+            match thereShouldBeNoOtherSquigglesHere with
+            | Some(true) ->
+                if squiggles.Length <> 1 then
+                    Assert.Fail(sprintf "Multiple squiggles when only one expected; expected only\r\n%A\r\ngot\r\n%A" expectedSquiggle squiggles)
+            | _ -> ()
+        else
+            Assert.Fail(sprintf "Expected %A but got %A" expectedSquiggle squiggles)
+  
+    member private this.VerifySquiggleContainedAtStartOfMarker(fileContents : string, marker : string, expectedSquiggle : (Microsoft.VisualStudio.FSharp.LanguageService.Severity * string)) = 
+        let (sln, proj, file) = this.CreateSingleFileProject(fileContents)
+        MoveCursorToStartOfMarker(file, marker)
+        let squiggles = GetSquigglesAtCursor(file)
+        if squiggles |> List.exists (fun (sev,msg) -> fst expectedSquiggle = sev && msg.Contains(snd expectedSquiggle)) then
+            ()  // ok, found it
+        else
+            Assert.Fail(sprintf "Expected %A but got %A" expectedSquiggle squiggles)
+
+    [<Test>]
+    member public this.``Error.Expression.IllegalIntegerLiteral``() = 
+        this.VerifySquiggleAtStartOfMarker(
+            fileContents = """
+                let _ = 1
+                let a = 0.1.(*MError1*)0
+                """,
+            marker = "(*MError1*)",
+            expectedSquiggle = (Microsoft.VisualStudio.FSharp.LanguageService.Severity.Error,
+                                 "Missing qualification after '.'")) 
+                               
+                     
+    [<Test>]
+    member public this.``Error.Expression.IncompleteDefine``() = 
+        this.VerifySquiggleAtStartOfMarker(
+            fileContents = """
+                let a = ;(*MError3*)""",
+            marker = "(*MError3*)",
+            expectedSquiggle= (Microsoft.VisualStudio.FSharp.LanguageService.Severity.Error,
+                              "Unexpected symbol ';' in binding")) 
+
+    [<Test>]
+    member public this.``Error.Expression.KeywordAsValue``() = 
+        this.VerifySquiggleAtStartOfMarker(
+            fileContents = """
+                let b =
+                type(*MError4*) 
+                """,
+            marker = "(*MError4*)",
+            expectedSquiggle= (Microsoft.VisualStudio.FSharp.LanguageService.Severity.Error,
+                              "Incomplete structured construct at or before this point in binding"))
+                              
+    [<Test>]
+    member public this.``Error.Type.WithoutName``() = 
+        this.VerifySquiggleAtStartOfMarker(
+            fileContents = """
+                type =(*MError5*)
+                ;;""",
+            marker = "(*MError5*)",
+            expectedSquiggle= (Microsoft.VisualStudio.FSharp.LanguageService.Severity.Error,
+                              "Unexpected symbol '=' in type name"))         
+    
+    [<Test>]                          
+    member public this.``AbstractClasses.Constructors.PositiveTests``() = 
+
+        let testCases = 
+            [
+            """
+[<AbstractClass>]
+type C(a : int) = 
+    new(a : string) = C(int a)
+    new(b) = match b with Some _ -> C(1) | _ -> C("")
+
+            """, ["C(1)"; "C(\"\")"; "C(int a)"]
+
+            """
+[<AbstractClass>]
+type C(a : int) = 
+    new(a : string) = new C(int a)
+    new(b) = match b with Some _ -> new C(1) | _ -> new C("")
+
+            """, ["C(1)"; "C(\"\")"; "C(int a)"]
+
+
+            """
+[<AbstractClass>]
+type O(o : int) = 
+    new() = O(1)
+            """, ["O(1)"]
+
+            """
+[<AbstractClass>]
+type O(o : int) = 
+    new() = new O(1)
+            """, ["O(1)"]
+
+
+            """
+[<AbstractClass>]
+type O(o : int) = 
+    new() = O() then printfn "A"
+            """, ["O()"]
+
+            """
+[<AbstractClass>]
+type O(o : int) = 
+    new() = new O(1) then printfn "A"
+            """, ["O(1)"]
+
+
+            """
+[<AbstractClass>]
+type D() = class end
+[<AbstractClass>]
+type E = 
+    inherit D
+    new() = { inherit D(); }
+            """, ["D();"]
+
+            ]
+
+        for (source, markers) in testCases do
+            printfn "AbstractClasses.Constructors.PositiveTests: testing %s, markers: %A" source markers
+            CheckSquiggles source markers <|
+                fun _ -> 
+                    function
+                    | [] -> () // OK : no squiggles expected
+                    | errs -> sprintf "Unexpected squiggles %A" errs |> Assert.Fail
+
+    [<Test>]                          
+    member public this.``AbstractClasses.Constructors.NegativeTests``() = 
+        let testCases = 
+            [
+            """
+[<AbstractClass>]
+type D = 
+    val d : D
+    new() = {d = D()}
+            """, ["D()", true]
+
+            """
+[<AbstractClass>]
+type D = 
+    val d : D
+    new() = {d = new D()}
+            """, ["D()", true]
+
+            """
+[<AbstractClass>]
+type Z() = 
+    new(a : int) = 
+        Z(10) then ignore(Z())
+            """, ["Z())", true]
+
+            """
+[<AbstractClass>]
+type Z() = 
+    new(a : int) = 
+        new Z(10) then ignore(new Z())
+            """, ["Z())", true]
+
+            """
+[<AbstractClass>]
+type X() = 
+    member val V : bool = true
+    new(_ : bool) = 
+            if X().V 
+            then X(true) 
+            else X()//1
+            then ignore(X())
+            """, ["X().V", true; "X())", true; "X()//1", false; "X(true) ", false]
+
+            """
+[<AbstractClass>]
+type X() = 
+    member val V : bool = true
+    new(_ : bool) = 
+            if (new X()).V 
+            then new X(true) 
+            else new X()//1 
+            then ignore(new X())
+            """, ["X()).V", true; "X())", true; "new X(true)", false; "X()//1", false ]
+
+            """
+[<AbstractClass>]
+type X() = 
+    member val V : bool = true
+    new(_ : bool) = 
+        let _ = 
+            if X().V 
+            then X(true) 
+            else X()//M
+        X()//1
+            then ignore(X())
+            """, ["X().V", true; "X(true) ", true; "X()//M", true; "X())", true; "X()//1", false]
+
+
+            """
+[<AbstractClass>]
+type X() = 
+    member val V : bool = true
+    new(_ : bool) = 
+        let _ = 
+            if (new X()).V 
+            then new X(true) 
+            else new X()//M
+        new X() //2
+            then ignore(new X())
+            """, ["X()).V", true; "X(true)", true; "X()//M", true; "X())", true; "new X() //2", false]
+            ]
+        for (source, markers) in testCases do
+            printfn "AbstractClasses.Constructors.NegativeTests: testing %s, markers: %A" source markers
+            let map = dict markers
+            let markers = List.map fst markers
+            CheckSquiggles source markers <|
+                fun marker -> 
+                    function
+                    | [] -> if map.[marker] then Assert.Fail("Squiggles expected") else ()
+                    | errs ->
+                        if not (map.[marker]) then Assert.Fail("Squiggles not expected")
+                        else
+                        for (sev, text) in errs do
+                            printfn "Actual squiggles at %s: Severity %A, text %s" marker sev text
+                            Assert.AreEqual(Microsoft.VisualStudio.FSharp.LanguageService.Severity.Error, sev, "Error severity expected")
+                            Assert.AreEqual("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.", text, "Unexpected error text")
+
+
+
+    [<Test>]
+    [<Category("TypeProvider")>]
+    member this.``TypeProvider.Error.VerbatimStringAccident.GoodErrorMessage``() = 
+        let r = [System.IO.Path.Combine(System.Environment.CurrentDirectory,@"UnitTestsResources\MockTypeProviders\DummyProviderForLanguageServiceTesting.dll")]
+        let (sln, proj, file) = this.CreateSingleFileProject("""type foo = N1.T<@"foo">""", references = r)
+        TakeCoffeeBreak(this.VS)// Wait for the background compiler to catch up.
+        MoveCursorToStartOfMarker(file, "1")
+        AssertEqual( [], GetSquigglesAtCursor(file) )  // no error messages here
+        MoveCursorToStartOfMarker(file, "T")
+        AssertEqual( [], GetSquigglesAtCursor(file) )  // no error messages here either
+        MoveCursorToStartOfMarker(file, "<@")
+        let squiggles = GetSquigglesAtCursor(file)
+        let expected = Microsoft.VisualStudio.FSharp.LanguageService.Severity.Error,
+                          """Unexpected quotation operator '<@' in type definition. If you intend to pass a verbatim string as a static argument to a type provider, put a space between the '<' and '@' characters."""
+        AssertEqual( [expected], squiggles )
+
+    [<Test>]
+    [<Category("TypeProvider")>]
+    member public this.``TypeProvider.WarningAboutEmptyAssembly`` () =
+        let emptyLoc = System.IO.Path.Combine(System.Environment.CurrentDirectory,@"UnitTestsResources\MockTypeProviders\EmptyAssembly.dll")
+        this.VerifySquiggleAtStartOfMarker(
+            fileContents = "type foo = N1.T<\"foo\"",
+            marker = "t",
+            expectedSquiggle= (Microsoft.VisualStudio.FSharp.LanguageService.Severity.Warning,
+                                "Referenced assembly '"+emptyLoc+"' has assembly level attribute 'Microsoft.FSharp.Core.CompilerServices.TypeProviderAssemblyAttribute' but no public type provider classes were found"),
+            // ensure that if you referenced two TP assemblies, one of which contained TPs, and the other did not, then you get the warning about a TP assembly with no TPs
+            addtlRefAssy = [emptyLoc; System.IO.Path.Combine(System.Environment.CurrentDirectory,@"UnitTestsResources\MockTypeProviders\DummyProviderForLanguageServiceTesting.dll")],
+            thereShouldBeNoOtherSquigglesHere=true)      
+
+    [<Test>]
+    [<Category("TypeProvider")>]
+    member public this.``TypeProvider.Approvals.ErrorWhenNotApproved`` () =
+        try
+            use _guard = this.UsingNewVS()
+            ClearAllTypeProviderApprovals()                
+            let solution = this.CreateSolution()
+            let project = CreateProject(solution,"testproject")
+            this.AddAssemblyReference(project,System.IO.Path.Combine(System.Environment.CurrentDirectory,@"UnitTestsResources\MockTypeProviders\DummyProviderForLanguageServiceTesting.dll"))
+            let file1 = AddFileFromText(project,"File1.fs", ["type foo = N1.T<"])
+            let file1 = OpenFile(project,"File1.fs")
+            MoveCursorToEndOfMarker(file1,"t")
+            let errs = GetSquigglesAtCursor(file1)
+            if not(errs |> List.exists (fun (sev,msg) -> 
+                        sev=Microsoft.VisualStudio.FSharp.LanguageService.Severity.Warning 
+                        && msg.Contains("is not trusted and will not be loaded for security reasons. This may cause subsequent build errors."))) then
+                Assert.Fail "did not find expected squiggle"
+            if errs.Length <> 1 then
+                Assert.Fail(sprintf "found extra squiggles; all are %A" errs)
+            // if multiple files are open, they all get the warning
+            let file2 = AddFileFromText(project,"File2.fs", ["let x = 3"])
+            let file2 = OpenFile(project,"File2.fs")
+            MoveCursorToEndOfMarker(file2,"l")
+            let errs = GetSquigglesAtCursor(file2)
+            if not(errs |> List.exists (fun (sev,msg) -> 
+                        sev=Microsoft.VisualStudio.FSharp.LanguageService.Severity.Warning 
+                        && msg.Contains("is not trusted and will not be loaded for security reasons. This may cause subsequent build errors."))) then
+                Assert.Fail "did not find expected squiggle"
+            if errs.Length <> 1 then
+                Assert.Fail(sprintf "found extra squiggles; all are %A" errs)
+        finally
+            ApproveAllMockTypeProviders()
+
+    [<Test>]
+    [<Category("TypeProvider")>]
+    [<Category("TypeProvider.StaticParameters")>]
+    member public this.``TypeProvider.Error.CodePrefix1.GoodErrorMessage`` () =
+        this.VerifySquiggleAtStartOfMarker(
+            fileContents = "type foo = N1.T<",
+            marker = "N1",
+            expectedSquiggle= (Microsoft.VisualStudio.FSharp.LanguageService.Severity.Error,
+                              "The static parameter 'Param1' of the provided type 'T' requires a value. Static parameters to type providers may be optionally specified using named arguments, e.g. 'T<Param1=...>'."),
+            addtlRefAssy = [System.IO.Path.Combine(System.Environment.CurrentDirectory,@"UnitTestsResources\MockTypeProviders\DummyProviderForLanguageServiceTesting.dll")])      
+
+    [<Test>]
+    [<Category("TypeProvider")>]
+    [<Category("TypeProvider.StaticParameters")>]
+    member public this.``TypeProvider.Error.CodePrefix2.GoodErrorMessage`` () =
+        this.VerifySquiggleAtStartOfMarker(
+            fileContents = "type foo = N1.T<\"foo\",",
+            marker = "N1",
+            expectedSquiggle= (Microsoft.VisualStudio.FSharp.LanguageService.Severity.Error,
+                              "The static parameter 'ParamIgnored' of the provided type 'T' requires a value. Static parameters to type providers may be optionally specified using named arguments, e.g. 'T<ParamIgnored=...>'."),
+            addtlRefAssy = [System.IO.Path.Combine(System.Environment.CurrentDirectory,@"UnitTestsResources\MockTypeProviders\DummyProviderForLanguageServiceTesting.dll")])      
+
+    [<Test>]
+    [<Category("TypeProvider")>]
+    [<Category("TypeProvider.StaticParameters")>]
+    member public this.``TypeProvider.Error.CodePrefix3.GoodErrorMessage`` () =
+        this.VerifySquiggleAtStartOfMarker(
+            fileContents = "
+                type foo = N1.T<\"foo\",
+                let z = 42",
+            marker = "let",
+            expectedSquiggle= (Microsoft.VisualStudio.FSharp.LanguageService.Severity.Error,
+                              "Expected type argument or static argument"),
+            addtlRefAssy = [System.IO.Path.Combine(System.Environment.CurrentDirectory,@"UnitTestsResources\MockTypeProviders\DummyProviderForLanguageServiceTesting.dll")])      
+
+    [<Test>]
+    [<Category("TypeProvider")>]
+    [<Category("TypeProvider.StaticParameters")>]
+    member public this.``TypeProvider.Error.CodePrefix4.GoodErrorMessage`` () =
+        this.VerifySquiggleAtStartOfMarker(
+            fileContents = "
+                type foo = N1.T<\"foo\",42
+                let z = 42",
+            marker = "let",
+            expectedSquiggle= (Microsoft.VisualStudio.FSharp.LanguageService.Severity.Error,
+                              "Incomplete structured construct at or before this point in type arguments. Expected ',', '>' or other token."),
+            addtlRefAssy = [System.IO.Path.Combine(System.Environment.CurrentDirectory,@"UnitTestsResources\MockTypeProviders\DummyProviderForLanguageServiceTesting.dll")])      
+
+    [<Test>]
+    [<Category("TypeProvider")>]
+    [<Category("TypeProvider.StaticParameters")>]
+    //This test case verify the error squiggle shows up when TypeProvider StaticParameter is Invalid 
+    //Dummy Type Provider exposes a parametric type (N1.T) that takes 2 static params (string * int) 
+    member public this.``TypeProvider.Error.InvalidStaticParameter`` () =
+        this.VerifySquiggleAtStartOfMarker(
+            fileContents = "
+                           type foo = N1.T< const 100(*Marker*),2>",
+            marker = "(*Marker*)",
+            expectedSquiggle= (Microsoft.VisualStudio.FSharp.LanguageService.Severity.Error,
+                               "This expression was expected to have type\n"+
+                               "    string    \n"+
+                               "but here has type\n"+
+                               "    int    "),
+            addtlRefAssy = [System.IO.Path.Combine(System.Environment.CurrentDirectory,@"UnitTestsResources\MockTypeProviders\DummyProviderForLanguageServiceTesting.dll")])   
+
+    
+    [<Test>]
+    [<Category("TypeProvider")>]
+    [<Category("TypeProvider.StaticParameters")>]
+    //This test case verify the No squiggle doesn't show up in the file content marker where TypeProvider line is
+    //Dummy Type Provider exposes a parametric type (N1.T) that takes 2 static params (string * int)
+    member public this.``TypeProvider.WithNoSquiggle`` () =
+        this.VerifyNoSquiggleAtStartOfMarker(
+            fileContents = """
+                           type foo = N1(*Marker*).T< const "Hello World",2>""",
+            marker = "(*Marker*)",
+            addtlRefAssy = [System.IO.Path.Combine(System.Environment.CurrentDirectory,@"UnitTestsResources\MockTypeProviders\DummyProviderForLanguageServiceTesting.dll")])     
+    
+   
+    [<Test>]
+    [<Category("TypeProvider")>]
+    [<Category("TypeProvider.StaticParameters")>]
+    //This test case verify the Warning squiggle does show up in the file content marker where TypeProvider line is
+    //Dummy Type Provider exposes a parametric type (N1.T) that takes 2 static params (string * int)
+    member public this.``TypeProvider.WarningSquiggle`` () =
+        this.VerifySquiggleAtStartOfMarker(
+            fileContents = """
+                           type foo = N1.T< 
+                               const(*Marker*) "Hello World",2>""",
+            marker = "(*Marker*)",
+            expectedSquiggle= (Microsoft.VisualStudio.FSharp.LanguageService.Severity.Warning,
+                                "Possible incorrect indentation: this token is "+
+                                "offside of context started at position (2:39). "+
+                                "Try indenting this token further or using "+
+                                "standard formatting conventions."),
+            addtlRefAssy = [System.IO.Path.Combine(System.Environment.CurrentDirectory,@"UnitTestsResources\MockTypeProviders\DummyProviderForLanguageServiceTesting.dll")])     
+
+
+    [<Test>]
+    member public this.``Waring.Construct.TypeMatchWithoutAnnotation``() = 
+        this.VerifySquiggleAtStartOfMarker(
+            fileContents = """
+                let f () = 
+                    let g1 (x:'a) = x
+                    let g2 (y:'a) = (y(*MWarning3*):string)
+                    g1 3, g1 "3", g2 "4" """,
+            marker = "(*MWarning3*)",
+            expectedSquiggle= (Microsoft.VisualStudio.FSharp.LanguageService.Severity.Warning,
+                              "This construct causes code to be less generic " +
+                              "than indicated by the type annotations. The " +
+                              "type variable 'a has been constrained to be " +
+                              "type 'string'."))  
+                                                      
+    [<Test>] 
+    member public this.``Warning.Expression.IncorrectFormat``() = 
+        this.VerifySquiggleAtStartOfMarker(
+            fileContents = """
+                let nConstant = 
+                100(*MWarning4*) """,
+            marker = "(*MWarning4*)",
+            expectedSquiggle= (Microsoft.VisualStudio.FSharp.LanguageService.Severity.Warning,
+                              "Possible incorrect indentation: this token is "+
+                              "offside of context started at position (2:17). "+
+                              "Try indenting this token further or using "+
+                              "standard formatting conventions."))                                    
+
+    [<Test>]
+    member public this.``Error.Method.ParameterNumDoseNotMatch``() =
+        this.VerifySquiggleAtStartOfMarker(
+            fileContents = """
+                open System
+                open System.IO
+
+                if File.Exists(aFile) then
+                    File.(aFile,"")(*M1*)""",
+            marker = "(*M1*)",
+            expectedSquiggle= (Microsoft.VisualStudio.FSharp.LanguageService.Severity.Error,
+                              "This construct is deprecated: This indexer notation has been removed from the F# language"))
+
+    (*    Now that the language service reports typecheck errors even if there are parse errors, this location
+    now has two errors.  And Salsa just picks the 'first' squiggle (based on some arbitrary implementation
+    artifacts of what order errors are put in the collection), so 'GetSquiggleAtCursor' is unreliable if there 
+    is more that on squiggle there. Workaround here is to look through the whole error list for what we're looking for.  *) 
+    [<Test>]
+    [<Ignore("Salsa limitation")>]                          
+    member public this.``Error.Identifer.IllegalFloatPointLiteral``() = 
+        this.VerifySquiggleAtStartOfMarker(
+            fileContents = """
+                let someFunction x.0.0(*MError2*) = 1""",
+            marker = "(*MError2*)",
+            expectedSquiggle= (Microsoft.VisualStudio.FSharp.LanguageService.Severity.Error,
+                                "Unexpected floating point literal in pattern. Expected identifier, '(', '(*)' or other token."))      
+    
+    
+    [<Test>]
+    member public this.ErrorSquiggleSpan() =
+        let fileContents = """
+            #light
+            let _ = 1
+            let a = 0.1.0(*MError1*)
+            ;;
+            let someFunction x.0.0(*MError2*) = 1
+            ;;
+            let a = ;(*MError3*)
+            ;;
+            let b =
+            type(*MError4*) 
+            ;;
+            type =(*MError5*)
+            ;;
+            """     
+        let (sln, proj, file) = this.CreateSingleFileProject(fileContents)  
+        let errors = GetErrors(proj)
+        let desiredError = errors |> List.tryFind (fun e -> e.Message = "Unexpected floating point literal in pattern. Expected identifier, '(', '(*)' or other token.")
+        match desiredError with
+        | None -> Assert.Fail("did not find expected error")
+        | Some(e) -> 
+            Assert.IsTrue(e.Context = TextSpan(iStartLine=5, iStartIndex=31, iEndLine=5, iEndIndex=34), "error had wrong location")   
+  
+    [<Test>]
+    member public this.``Error.TypeCheck.ParseError.Bug67133``() =
+        // Note: no 'open System', so DateTime is unknown
+        this.VerifySquiggleAtStartOfMarker(
+            fileContents = """
+                let gDateTime (arr: DateTime(*Mark*)[]) =
+                     arr.[0].""",
+            marker = "(*Mark*)",
+            expectedSquiggle= (Microsoft.VisualStudio.FSharp.LanguageService.Severity.Error,"The type 'DateTime' is not defined"))
+ 
+    [<Test>]
+    member public this.``Error.CyclicalDeclarationDoesNotCrash``() =
+        // Note: no 'open System', so DateTime is unknown
+        this.VerifySquiggleAtStartOfMarker(
+            fileContents = """type A(*Mark*) = int * A""",
+            marker = "(*Mark*)",
+            expectedSquiggle= (Microsoft.VisualStudio.FSharp.LanguageService.Severity.Error,"This type definition involves an immediate cyclic reference through an abbreviation"))       
+
+    /// FEATURE: Flags from the MSBuild compile target are respected.
+    [<Test>]
+    member public this.``Warning.FlagsAndSettings.TargetOptionsRespected``() =  
+        let fileContent = """
+            [<System.Obsolete("x")>]
+            let fn x = 0
+            let y = fn(*Mark*) 1"""
+        /// Make sure the warning would be there.
+        this.VerifySquiggleAtStartOfMarker(fileContent,"(*Mark*)",(Microsoft.VisualStudio.FSharp.LanguageService.Severity.Warning, "This construct is deprecated. x"))       
+
+    /// When a .fs file is opened with no project context we do show squiggles
+    /// for missing types etc.
+    [<Test>]
+    [<Category("PerfCheck")>]
+    member public this.``OrphanFs.MissingTypesShouldNotShowErrors``() =
+        let fileContent = """open Unknown(*Mark*)"""
+        this.VerifySquiggleContainedAtStartOfMarker(fileContent,"(*Mark*)",(Microsoft.VisualStudio.FSharp.LanguageService.Severity.Error, "Unknown"))  
+        
+    /// When a .fs file is opened with no project context we still do want to show squiggles
+    /// for parse errors which could not have been caused by a missing reference or prior source file.
+    [<Test>]
+    member public this.``OrphanFs.ParseErrorsStillShow``() =  
+        let fileContent = """let foo = let(*Mark*)"""
+        this.VerifySquiggleContainedAtStartOfMarker(fileContent,"(*Mark*)",(Microsoft.VisualStudio.FSharp.LanguageService.Severity.Error, "Block following "))  
+
+    /// FEATURE: If a .fs file has a BuildAction other than "Compile", it behaves like a
+    /// single-file-project with regards to intellisense.
+    [<Test>]
+    [<Category("PerfCheck")>]
+    member public this.``Project.FsFileWithBuildActionOtherThanCompileBehavesLikeSingleFileProject``() =
+        use _guard = this.UsingNewVS()
+        let solution = this.CreateSolution()
+        let project = CreateProject(solution,"testproject")
+        let file1 = AddFileFromText(project,"File1.fs",
+                                    ["let bob = 42"])
+
+        let file2 = AddFileFromTextEx(project, "File2.fs", "File2.fs", BuildAction.None,
+                                    ["let i = 4"
+                                     "let r = i.ToString()"
+                                     "let x = File1.bob"])
+        let file1 = OpenFile(project,"File1.fs")
+        let file2 = OpenFile(project,"File2.fs")
+        // file2 should not be able to 'see' file1
+        MoveCursorToEndOfMarker(file2,"File1")
+        let squiggle = GetSquiggleAtCursor(file2)
+        Assert.IsTrue(snd squiggle.Value |> fun str -> str.Contains("The namespace"))// The namespace or module 'File1' is not defined
+
+    /// FEATURE: Errors in the code are underlined with red squiggles and a clickable description of the error appears in the Error List.
+    [<Test>]
+    [<Category("PerfCheck")>]
+    member public this.``Basic.Case1``() =
+        let fileContent = """
+            let x = 3
+            let y = x(*Mark*) 4
+            let arr = [| 1; 2; 3 |]"""
+        this.VerifySquiggleContainedAtStartOfMarker(fileContent,"(*Mark*)",(Microsoft.VisualStudio.FSharp.LanguageService.Severity.Error, "This value is not a function and cannot be applied")) 
+
+    [<Test>]
+    [<Category("PerfCheck")>]
+    member public this.``Basic.Case2``() =
+        let fileContent = """
+            let x(*Mark*) = 3
+            let y = x 4
+            let arr = [| 1; 2; 3 |]"""            
+        // test an error-free location
+        this.VerifyNoSquiggleAtStartOfMarker(fileContent,"(*Mark*)")
+
+
+    [<Test>]
+    member public this.``Multiline.Bug5449.Case1``() =
+        let fileContent = """
+            let f x = 1
+            let r = f(*Mark*)
+                           234
+                           567
+            """
+        this.VerifySquiggleContainedAtStartOfMarker(fileContent,"(*Mark*)",(Microsoft.VisualStudio.FSharp.LanguageService.Severity.Error, "This value is not a function and cannot be applied"))  
+
+    [<Test>]
+    member public this.``Multiline.Bug5449.Case2``() =
+        let fileContent = """
+            let f x = 1
+            let r = f
+                           234(*Mark*)
+                           567
+            """
+        this.VerifySquiggleContainedAtStartOfMarker(fileContent,"(*Mark*)",(Microsoft.VisualStudio.FSharp.LanguageService.Severity.Error, "This value is not a function and cannot be applied"))  
+        
+    [<Test>]
+    member public this.``ErrorAtTheEndOfFile``() =
+        let fileContent = """3 + """
+        let (sln, proj, file) = this.CreateSingleFileProject(fileContent)
+        
+        MoveCursorToEndOfMarker(file,"3 + ") 
+        let squiggles = GetSquigglesAtCursor(file)
+        let expectedSquiggle = (Microsoft.VisualStudio.FSharp.LanguageService.Severity.Error,"Unexpected end")
+        if squiggles |> List.exists (fun (sev,msg) -> fst expectedSquiggle = sev && msg.Contains(snd expectedSquiggle)) then
+            ()  // ok, found it
+        else
+            Assert.Fail(sprintf "Expected %A but got %A" expectedSquiggle squiggles)
+
+    [<Test>]
+    member public this.``InComputationExpression.6095_a``() =
+        let code = 
+                                    ["let a = async {"
+                                     "   let! [| r1; r2 |] = Async.Parallel [| async.Return(1); async.Return(2) |]"
+                                     "   let yyyy = 4"
+                                     "   return r1,r2 }"]
+        let (_,_, file) = this.CreateSingleFileProject(code)
+        
+        // in the bug, the squiggle did not appear at the actual problem
+        MoveCursorToEndOfMarker(file,"r1;") 
+        let ans = GetSquiggleAtCursor(file)
+        match ans with
+        | Some(sev,msg) -> AssertEqual(Microsoft.VisualStudio.FSharp.LanguageService.Severity.Warning,sev)
+                           AssertContains(msg,"Incomplete pattern matches on this expression. For example, the value '[|_; _; _|]' may indicate a case not covered by the pattern(s).")
+        | _ -> Assert.Fail("Expected squiggle in computation expression")
+
+        // in the bug, the squiggle was on the 'whole rest of the computation'
+        MoveCursorToEndOfMarker(file,"yyy") 
+        let ans = GetSquiggleAtCursor(file)
+        AssertNoSquiggle(ans)
+
+        MoveCursorToEndOfMarker(file,"retur") 
+        let ans = GetSquiggleAtCursor(file)
+        AssertNoSquiggle(ans)
+
+    [<Test>]
+    member public this.``InComputationExpression.6095_b``() =
+        let code = 
+                                    ["let a = async {"
+                                     "    for [|x;y|] in [| [|42|] |] do () }"]
+        let (_, _, file) = this.CreateSingleFileProject(code)
+        
+        // in the bug, the squiggle covered whole for..do
+        MoveCursorToEndOfMarker(file,"fo") 
+        let ans = GetSquiggleAtCursor(file)
+        AssertNoSquiggle(ans)
+
+        MoveCursorToEndOfMarker(file,"x") 
+        let ans = GetSquiggleAtCursor(file)
+        AssertNoSquiggle(ans)
+
+        MoveCursorToEndOfMarker(file,"in") 
+        let ans = GetSquiggleAtCursor(file)
+        AssertNoSquiggle(ans)
+
+        MoveCursorToEndOfMarker(file,"do") 
+        let ans = GetSquiggleAtCursor(file)
+        AssertNoSquiggle(ans)
+
+        MoveCursorToEndOfMarker(file,"42") 
+        let ans = GetSquiggleAtCursor(file)
+        match ans with
+        | Some(sev,msg) -> AssertEqual(Microsoft.VisualStudio.FSharp.LanguageService.Severity.Warning,sev)
+                           AssertContains(msg,"Incomplete pattern matches on this expression. For example, the value '[|_; _; _|]' may indicate a case not covered by the pattern(s).")
+        | _ -> Assert.Fail("Expected squiggle in computation expression")
+
+    [<Test>]
+    member public this.``InComputationExpression.6095_c``() =  // this one is not in a computation expression actually
+        let code = ["let f = function | [| a;b |] -> ()"]
+        let (_, _, file) = this.CreateSingleFileProject(code)
+        
+        // in the bug, the squiggle covered whole function... end of line
+        MoveCursorToEndOfMarker(file,"a") 
+        let ans = GetSquiggleAtCursor(file)
+        AssertNoSquiggle(ans)
+
+        MoveCursorToEndOfMarker(file,"(") 
+        let ans = GetSquiggleAtCursor(file)
+        AssertNoSquiggle(ans)
+
+        MoveCursorToEndOfMarker(file,"func") // we just want the squiggle under the word 'function', which is shorthand for 'fun x -> match x when' (squiggle would go under 'x')
+        let ans = GetSquiggleAtCursor(file)
+        match ans with
+        | Some(sev,msg) -> AssertEqual(Microsoft.VisualStudio.FSharp.LanguageService.Severity.Warning,sev)
+                           AssertContains(msg,"Incomplete pattern matches on this expression. For example, the value '[|_; _; _|]' may indicate a case not covered by the pattern(s).")
+        | _ -> Assert.Fail("Expected squiggle in computation expression")
+
+    [<Test>]
+    member public this.``InComputationExpression.6095_d``() =  // this one is not in a computation expression actually
+        let code = ["for [|a;b|] in [| [|42|] |] do ()"]
+        let (_, _, file) = this.CreateSingleFileProject(code)
+        
+        // in the bug, the squiggle covered whole for..()
+        MoveCursorToEndOfMarker(file,"fo") 
+        let ans = GetSquiggleAtCursor(file)
+        AssertNoSquiggle(ans)
+
+        MoveCursorToEndOfMarker(file,"a") 
+        let ans = GetSquiggleAtCursor(file)
+        match ans with
+        | Some(sev,msg) -> AssertEqual(Microsoft.VisualStudio.FSharp.LanguageService.Severity.Warning,sev)
+                           AssertContains(msg,"Incomplete pattern matches on this expression. For example, the value '[|_; _; _|]' may indicate a case not covered by the pattern(s).")
+        | _ -> Assert.Fail("Expected squiggle in computation expression")
+
+        MoveCursorToEndOfMarker(file,"in") 
+        let ans = GetSquiggleAtCursor(file)
+        AssertNoSquiggle(ans)
+
+        MoveCursorToEndOfMarker(file,"do") 
+        let ans = GetSquiggleAtCursor(file)
+        AssertNoSquiggle(ans)
+
+        MoveCursorToEndOfMarker(file,"42")
+        let ans = GetSquiggleAtCursor(file)
+        AssertNoSquiggle(ans)
+
+
+    [<Test>]
+    member public this.``GloballyScoped.6284``() =
+        use _guard = this.UsingNewVS()
+        let solution = this.CreateSolution()
+        let project = CreateProject(solution,"testproject")
+        let bfile = AddFileFromText(project,"Bar.fs",
+                                    ["namespace global
+                                        type Bar() = 
+                                          member this.Y = 1"])
+        let programFile = AddFileFromText(project,"Program.fs", ["let b = global.Bar()"])
+        let programFile = OpenFile(project,"Program.fs")       
+        // test an error
+        MoveCursorToEndOfMarker(programFile,"let b = glo") 
+        let ans = GetSquiggleAtCursor(programFile)
+        AssertNoSquiggle(ans)
+                
+    [<Test>]
+    member public this.``InComputationExpression.914685``() =
+        let code = ["async { if true then return 1 } |> ignore"]
+        let (_, _, file) = this.CreateSingleFileProject(code)
+        // test an error
+        MoveCursorToEndOfMarker(file,"async { if tr") 
+        let ans = GetSquiggleAtCursor(file)
+        match ans with
+            | Some(sev,msg) -> AssertEqual(Microsoft.VisualStudio.FSharp.LanguageService.Severity.Error,sev)
+                               AssertContains(msg,"The type 'int'")
+            | _ -> Assert.Fail("Expected squiggle in computation expression")
+
+    [<Test>]
+    member public this.``InComputationExpression.214740``() =
+        this.VerifySquiggleAtStartOfMarker(
+            fileContents = """
+                let x = 1 + ""    // type error, but no squiggle if parse error below
+                let l = [1;2]
+                seq {             // (seq or async or whatever, hits same path through the parser)
+                    for x in l.   // delete this dot and squiggle above appears
+                }""",
+            marker = "\"\"",
+            expectedSquiggle = (Microsoft.VisualStudio.FSharp.LanguageService.Severity.Error,
+                                 "The type 'string' does not match the type 'int'")) 
+
+    /// Extra endif
+    [<Test>]
+    member public this.``ExtraEndif``() =
+        let fileContent = """
+            #if UNDEFINED //(*If*)
+                let x = 1(*Inactive*)
+            #else //(*Else*)
+                let(*Active*) x = 1
+            #endif //(*Endif*)
+            #endif(*Mark*) //(*Extra endif*)"""
+        this.VerifySquiggleContainedAtStartOfMarker(fileContent,"(*Mark*)",(Microsoft.VisualStudio.FSharp.LanguageService.Severity.Error, "#endif has no matching #if in implementation file")) 
+         
+    [<Test>]
+    member public this.``DirectivesInString``() =
+        let fileContent = """
+            #if UNDEFINED
+            #else(*Mark*)
+            let s = "
+            #endif
+            "
+            let testme = 1"""
+        this.VerifySquiggleContainedAtStartOfMarker(fileContent,"(*Mark*)",(Microsoft.VisualStudio.FSharp.LanguageService.Severity.Error, "No #endif found"))           
+
+    (* Various #if/#else/#endif errors -------------------------------------------------- *)
+    
+    member private this.TestSquiggle error lines marker expected =
+        let code = "#light"::""::lines
+        let (_, _, file) = this.CreateSingleFileProject(code, defines = ["FOO"])
+        MoveCursorToStartOfMarker(file, marker)
+        let squiggle = GetSquiggleAtCursor(file)
+        match squiggle with
+        | Some(sev,msg) -> AssertEqual((if error then Microsoft.VisualStudio.FSharp.LanguageService.Severity.Error else Microsoft.VisualStudio.FSharp.LanguageService.Severity.Warning),sev)
+                           AssertContains(msg, expected)
+        | _ -> Assert.Fail(sprintf "No squiggle seen. Expected: '%s'" expected)   
+        
+    [<Test>]
+    member public this.``Squiggles.HashNotFirstSymbolA``() =
+        this.TestSquiggle true [ "(**) #if IDENT"; "#endif" ] "if" "#if directive must appear as the first non-whitespace"
+
+    [<Test>]
+    member public this.``Squiggles.HashNotFirstSymbolB``() =
+        this.TestSquiggle true [ "#if FOO"; "(**) #else"; "#endif" ] "else" "#else directive must appear as the first non-whitespace"
+
+    [<Test>]
+    member public this.``Squiggles.HashNotFirstSymbolC``() =
+        this.TestSquiggle true [ "#if IDENT"; "#else"; "(**) #endif" ] "endif" "#endif directive must appear as the first non-whitespace"
+        
+    [<Test>]
+    member public this.``Squiggles.HashIfWithoutIdent``() =
+        this.TestSquiggle true [ "#if"; "#endif" ] "if" "#if directive should be immediately followed by an identifier"
+
+    [<Test>]
+    member public this.``Squiggles.HashIfWrongExpr``() =
+        this.TestSquiggle true [ "#if !IDENT"; "#endif" ] "if" "#if directive should be immediately followed by an identifier"
+
+    [<Test>]
+    member public this.``Squiggles.HashIfWithMultilineComment``() =
+        this.TestSquiggle true [ "#if IDENT (* aaa *)"; "#endif" ] "(* aaa" "Expected single line comment or end of line"
+
+    [<Test>]
+    member public this.``Squiggles.HashIfWithUnexpected``() =
+        this.TestSquiggle true [ "#if IDENT whatever"; "#endif" ] "whatever" "Expected single line comment or end of line"
+
+     // FEATURE: Touching a depended-upon file will cause a intellisense to update in the currently edited file.
+    [<Test>]
+    member public this.``Refresh.RefreshOfDependentOpenFiles.Bug2166.CaseA``() =    
+        use _guard = this.UsingNewVS()
+        let gpatcc = GlobalParseAndTypeCheckCounter.StartNew(this.VS)
+        let solution = this.CreateSolution()
+        let project = CreateProject(solution,"testproject")
+        printfn "Adding file1"
+        let file1 = AddFileFromText(project,"File1.fs", 
+                                    ["#light"
+                                     "module Module1"
+                                    ])
+        let file1 = OpenFile(project,"File1.fs")
+        gpatcc.AssertExactly(AA[file1],AA[file1], true (* deleted, because a new file was added to the project *))
+
+        printfn "Adding file2"
+        let gpatcc = GlobalParseAndTypeCheckCounter.StartNew(this.VS)
+        let file2 = AddFileFromText(project,"File2.fs",
+                                    ["#light"
+                                     "open Module2"
+                                     ])
+        let file2 = OpenFile(project,"File2.fs")
+        gpatcc.AssertExactly(AA[file1;file2],AA[file1;file2], true (* deleted, because a new file was added to the project *))
+        
+        let gpatcc = GlobalParseAndTypeCheckCounter.StartNew(this.VS)
+        // Expect an error here because of reference to nonexistent Module2
+        MoveCursorToEndOfMarker(file2,"open Modu")
+        let ans = GetSquiggleAtCursor(file2)
+        AssertSquiggleIsErrorContaining(ans, "Module2")                    
+        gpatcc.AssertExactly(notAA[],notAA[])
+        
+        // Fix File1.fs so that it contains Module2
+        printfn "Fixing file1 in memory"
+        ReplaceFileInMemory file1 
+                                ["#light"
+                                 "module Module2"]
+                                 
+        // Assertion below is very subtle.  Here's what happened.  After opening file1, we opened file2.  This changed the contents 
+        // of the project file, and focused file2 (and unfocused file1).  Since then, we have never done anything to file1, not even
+        // OnIdle (which salsa only does for currently-focused-file), and thus when we touch file1 again, it falls into the logic
+        // in servicem.fs here:
+        // Furthermore, if we know our project is out-of-date, this may mean that dependent DLLs may have changed on disk without us knowing, 
+        // since we only just started listening for those changes a moment ago in the SetDependencyFiles() call.  So behave just as if we were 
+        // just notified that those dependency files changed.  (In the future, it would be good to partition a source file's dependencies into
+        // 'project' dependencies (that only depend on the IProjectSite, e.g. project/asseembly references) and 'source' dependencies (e.g. #r's).)
+        //if outOfDateProjectFileNames.Contains(projectFileName) then
+        //    this.Parser.InvalidateConfiguration(checkOptions)
+        // which assumes 'the worst' and calls InvalidateConfiguration (which calls InvalidateBuildCacheEntry, which deletes the IncrementalBuilder).
+        // I am happy to have this under test.
+        // The next test below (Case B) simulates behavior more like VS, which would be idling all the open files.
+        gpatcc.AssertExactly(AA[file1;file2], AA[file1;file2], true)
+        let gpatcc = GlobalParseAndTypeCheckCounter.StartNew(this.VS)
+        printfn "Fixing file1 on disk"
+        SaveFileToDisk file1      
+        gpatcc.AssertExactly(notAA[file1],notAA[file1;file2])
+        let gpatcc = GlobalParseAndTypeCheckCounter.StartNew(this.VS)
+        MoveCursorToEndOfMarker(file2,"open Modu") // This switches focus back to file2
+        TakeCoffeeBreak(this.VS)
+        let ans = GetSquiggleAtCursor(file2)
+        AssertNoSquiggle(ans)
+        gpatcc.AssertExactly(notAA[],notAA[])
+
+     // FEATURE: Touching a depended-upon file will cause a intellisense to update in the currently edited file.
+    [<Test>]
+    member public this.``Refresh.RefreshOfDependentOpenFiles.Bug2166.CaseB``() =  
+        use _guard = this.UsingNewVS()  
+        let gpatcc = GlobalParseAndTypeCheckCounter.StartNew(this.VS)
+        let solution = this.CreateSolution()
+        let project = CreateProject(solution,"testproject")
+        printfn "Adding file1"
+        let file1 = AddFileFromText(project,"File1.fs", 
+                                    ["#light"
+                                     "module Module1"
+                                    ])
+        let file1 = OpenFile(project,"File1.fs")
+        gpatcc.AssertExactly(AA[file1],AA[file1], true (* deleted, because a new file was added to the project *))
+
+        printfn "Adding file2"
+        let gpatcc = GlobalParseAndTypeCheckCounter.StartNew(this.VS)
+        let file2 = AddFileFromText(project,"File2.fs",
+                                    ["#light"
+                                     "open Module2"
+                                     ])
+        let file2 = OpenFile(project,"File2.fs")
+        // See long comment in (Case A), above.
+        // The first time we glance at file1 since the project file changed (file2 was added) will delete.
+        MoveCursorToEndOfMarker(file1,"#light")  // focus file1, so it gets idled
+        gpatcc.AssertExactly(AA[file1;file2],AA[file1;file2], true (* deleted, because a new file was added to the project *))
+        
+        let gpatcc = GlobalParseAndTypeCheckCounter.StartNew(this.VS)
+        // Expect an error here because of reference to nonexistent Module2
+        MoveCursorToEndOfMarker(file2,"open Modu")
+        let ans = GetSquiggleAtCursor(file2)
+        AssertSquiggleIsErrorContaining(ans, "Module2")                    
+        gpatcc.AssertExactly(notAA[],notAA[])
+        
+        // Fix File1.fs so that it contains Module2
+        printfn "Fixing file1 in memory"
+        ReplaceFileInMemory file1 
+                                ["#light"
+                                 "module Module2"]
+        gpatcc.AssertExactly(notAA[],notAA[])  // incremental builder does not see in-memory changes
+        let gpatcc = GlobalParseAndTypeCheckCounter.StartNew(this.VS)
+        printfn "Fixing file1 on disk"
+        SaveFileToDisk file1      
+        gpatcc.AssertExactly(notAA[file1],notAA[file1;file2])
+        let gpatcc = GlobalParseAndTypeCheckCounter.StartNew(this.VS)
+        MoveCursorToEndOfMarker(file2,"open Modu") // This switches focus back to file2
+        TakeCoffeeBreak(this.VS)
+        let ans = GetSquiggleAtCursor(file2)
+        AssertNoSquiggle(ans)
+        gpatcc.AssertExactly(notAA[],notAA[])
+        
+    // FEATURE: Give a nice error message when a type in a unreferenced dependant assembly is used
+    [<Test>]
+    member public this.``MissingDependencyReferences.MissingAssemblyErrorMessage``() = 
+        let code = 
+                                    ["#light"
+                                     "let myForm = new System.Windows.Forms.Form()"
+                                     "let bounds = myForm.Bounds"
+                                    ]
+        let (_,_, file) = this.CreateSingleFileProject(code, references = ["System"; "System.Windows.Forms"])
+        MoveCursorToEndOfMarker(file,"let bounds = myFo")
+        let ans = GetSquiggleAtCursor(file)
+        match ans with
+        | Some(sev,msg) -> AssertEqual(Microsoft.VisualStudio.FSharp.LanguageService.Severity.Error,sev)
+                           AssertContains(msg,"System.Drawing")
+                           AssertContains(msg,"You must add a reference")
+        | _ -> Assert.Fail("No squiggle seen")  
+
+
+//Allow the SquiggleTests run under different context
+namespace UnitTests.Tests.LanguageService.Squiggle
+open UnitTests.Tests.LanguageService
+open UnitTests.TestLib.LanguageService
+open UnitTests.TestLib.ProjectSystem
+open NUnit.Framework
+open Salsa.Salsa
+
+// context msbuild
+[<TestFixture>] 
+[<Category("LanguageService.MSBuild")>]
+type ``MSBuild`` = 
+   inherit SquiggleTests
+   new() = { inherit SquiggleTests(VsOpts = fst (Models.MSBuild())); }
+
+// Context project system
+[<TestFixture>] 
+[<Category("LanguageService.ProjectSystem")>]
+type ``ProjectSystem`` = 
+    inherit SquiggleTests
+    new() = { inherit SquiggleTests(VsOpts = LanguageServiceExtension.ProjectSystem); } 
diff --git a/vsintegration/src/unittests/Tests.LanguageService.TimeStamp.fs b/vsintegration/src/unittests/Tests.LanguageService.TimeStamp.fs
new file mode 100644
index 0000000..5484632
--- /dev/null
+++ b/vsintegration/src/unittests/Tests.LanguageService.TimeStamp.fs
@@ -0,0 +1,332 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+namespace UnitTests.Tests.LanguageService
+
+open System
+open System.IO
+open NUnit.Framework
+open Salsa.Salsa
+open Salsa.VsOpsUtils
+open UnitTests.TestLib.Salsa
+open UnitTests.TestLib.Utils
+open UnitTests.TestLib.LanguageService
+
+type TimeStampTests()  = 
+    inherit LanguageServiceBaseTests()
+
+    (* Timings ----------------------------------------------------------------------------- *)
+    let stopWatch = new System.Diagnostics.Stopwatch()
+    let ResetStopWatch() = stopWatch.Reset(); stopWatch.Start()
+    let time1 op a message = 
+        ResetStopWatch()
+        let result = op a
+        printf "%s %d ms\n" message stopWatch.ElapsedMilliseconds
+        result
+
+    let ShowErrors(project:OpenProject) =     
+        for error in (GetErrors(project)) do
+            printf "%s\n" (error.ToString()) 
+
+    let AssertNoErrorsOrWarnings(project:OpenProject) = 
+        let count = List.length (GetErrors(project))
+        if count<>0 then
+            printf "Saw %d errors and expected none.\n" count
+            AssertEqual(0,count)
+
+    let AssertNoErrorSeenContaining(project:OpenProject,text) =
+        let matching = (GetErrors(project)) |> List.filter (fun e->e.ToString().Contains(text))
+        match matching with 
+        | [] -> ()
+        | _ -> 
+            ShowErrors(project)
+            failwith (sprintf "Error seen containing \"%s\"" text)  
+
+    // In this bug, if you clean the dependent project, the dependee started getting errors again about the unresolved assembly.
+    // The desired behavior is like C#, which is if the assembly disappears from disk, we use cached results of last time it was there.
+    [<Test>]
+    member public this.``Regression.NoError.Timestamps.Bug3368b``() =
+        use _guard = this.UsingNewVS()
+        let solution = this.CreateSolution()
+        // Handy for this test: 
+        //Trace.Log <- "ChangeEvents;IncrementalBuildCommandLineMessages;SyncOp;CompilerServices"
+              
+        // Create the projects/
+        let project1 = CreateProject(solution,"testproject1")
+        let project2 = CreateProject(solution,"testproject2")                
+        SetConfigurationAndPlatform(project1, "Debug|AnyCPU")  // maybe due to msbuild bug on dev10, we must set config/platform when building with ProjectReferences
+        SetConfigurationAndPlatform(project2, "Debug|AnyCPU")  // maybe due to msbuild bug on dev10, we must set config/platform when building with ProjectReferences
+        let file1 = AddFileFromText(project1,"File1.fs", ["#light"
+                                                          "let xx = 42"
+                                                          "printfn \"hi\""])
+        let file2 = AddFileFromText(project2,"File2.fs", ["#light"
+                                                          "let yy = File1.xx"
+                                                          "printfn \"hi\""])      
+        // Add a project-to-project reference.
+        // WARNING: See bug 4434 - when unit testing this actually goes and builds project1!!!!
+        AddProjectReference(project2,project1)
+        TakeCoffeeBreak(this.VS) // Dependencies between projects get registered for file-watching during OnIdle processing
+        AssertNoErrorsOrWarnings(project1)
+        AssertNoErrorsOrWarnings(project2)
+
+        // Now build project1
+        printfn "building dependent project..."
+        Build project1 |> ignore
+        TakeCoffeeBreak(this.VS) 
+        
+        // Open files in editor.
+        let file1 = OpenFile(project1,"File1.fs")
+        let file2 = OpenFile(project2,"File2.fs")
+
+        // Now clean project1
+        printfn "cleaning dependent project..."
+        BuildTarget(project1, "Clean") |> ignore
+        TakeCoffeeBreak(this.VS) 
+        AssertNoErrorsOrWarnings(project1)
+        AssertNoErrorsOrWarnings(project2)  // this is key, project2 remembers what used to be on disk, does not fail due to missing assembly
+
+    // In this bug, the referenced project output didn't exist yet. Building dependee should cause update in dependant
+    [<Test>]
+    member public this.``Regression.NoContainedString.Timestamps.Bug3368a``() =
+        use _guard = this.UsingNewVS()
+        let solution = this.CreateSolution()
+        // Handy for this test: Trace.Log <- "ChangeEvents;IncrementalBuildCommandLineMessages"
+        // Create the projects/
+        let project1 = CreateProject(solution,"testproject1")
+        let project2 = CreateProject(solution,"testproject2")    
+        SetConfigurationAndPlatform(project1, "Debug|AnyCPU")  // maybe due to msbuild bug on dev10, we must set config/platform when building with ProjectReferences
+        SetConfigurationAndPlatform(project2, "Debug|AnyCPU")  // maybe due to msbuild bug on dev10, we must set config/platform when building with ProjectReferences
+        let file1 = AddFileFromText(project1,"File1.fs", ["#light"])
+        let file2 = AddFileFromText(project2,"File2.fs", ["#light"])
+        
+        // Add a project-to-project reference. 
+        // WARNING: See bug 4434 - when unit testing this actually goes and builds project1!!!!
+        AddProjectReference(project2,project1)
+        
+        // Open files in editor.
+        let file1 = OpenFile(project1,"File1.fs")
+        let file2 = OpenFile(project2,"File2.fs")
+        
+        // Wait for things to settle down and make sure there is an error
+        TakeCoffeeBreak(this.VS) 
+        // This assert no longer holds because project1 has inadvertently been built - see bug 4434 and comment above
+        //AssertExactlyOneErrorSeenContaining(project2, "project1")
+               
+        // Now build project1
+        Build project1 |> ignore
+        TakeCoffeeBreak(this.VS) 
+        AssertNoErrorSeenContaining(project2, "project1")
+
+   // FEATURE: OnIdle() will reprocess open dirty files, even if those file do not currently have editor focus
+    // [<Test>] TODO This test does not work because the unit tests do not cover product code that implements this feature
+    member public this.``Timestamps.Bug3368c``() =
+        use _guard = this.UsingNewVS()
+        let solution = this.CreateSolution()
+        // Handy for this test: 
+        //Trace.Log <- "ChangeEvents;IncrementalBuildCommandLineMessages;SyncOp;CompilerServices"
+        
+        // Create the projects/
+        let project1 = CreateProject(solution,"testproject1")
+        let project2 = CreateProject(solution,"testproject2")                
+        let file1 = AddFileFromText(project1,"File1.fs", ["#light"
+                                                          "let xx = 42"
+                                                          "printfn \"hi\""])
+        let file2 = AddFileFromText(project2,"File2.fs", ["#light"
+                                                          "let yy = File1.xx"
+                                                          "printfn \"hi\""])
+        
+        // Add an assembly reference between the projects (a P2P would fall victim to 4434)
+        let p1exe = BuildTarget(project1, "Clean")  // just a handy way to get the filename of the exe that would be built
+        this.AddAssemblyReference(project2, p1exe.ExecutableOutput)
+
+        // open a file to see the errors
+        let file2 = OpenFile(project2,"File2.fs")
+        TakeCoffeeBreak(this.VS)
+        
+        let errs = GetErrors(project2)
+        Assert.IsTrue(List.length errs > 0, "There should be errors (unresolved reference)")
+
+        // switch focus to a different file (to turn off 'focus' idle processing for file2)
+        let file1 = OpenFile(project1,"File1.fs")
+
+        // Now build project1
+        printfn "building dependent project..."
+        Build project1 |> ignore
+        let errs = GetErrors(project2)
+        Assert.IsTrue(List.length errs > 0, "There should be errors (unresolved reference)")
+        
+        TakeCoffeeBreak(this.VS) // the code that should clear out the errors is in LanguageService.cs:LanguageService.OnIdle(), 
+                          // but unit tests do not call this FSharp.LanguageService.Base code; TakeCoffeeBreak(this.VS) just simulates
+                          // idle processing for the currently-focused file
+        printfn "after idling, file2 errors should be cleared even though file2 is not focused"
+        AssertNoErrorsOrWarnings(project2)
+
+   // FEATURE: When a referenced assembly's timestamp changes the reference is reread.
+    [<Test>]
+    member public this.``Timestamps.ReferenceAssemblyChangeAbsolute``() =
+        use _guard = this.UsingNewVS()
+        let solution = this.CreateSolution()
+        let project1 = CreateProject(solution,"testproject1")
+        
+        let file1 = AddFileFromText(project1,"File1.fs",
+                                    ["#light"]
+                                     )
+        let file1 = OpenFile(project1,"File1.fs")
+        let project2 = CreateProject(solution,"testproject2")
+        let file2 = AddFileFromText(project2,"File2.fs",
+                                    ["#light"
+                                     "File1.File1."
+                                     "()"])
+        let file2 = OpenFile(project2,"File2.fs")
+        
+        // Build project1 which will later have the type being referenced by project2
+        let project1Dll = time1 Build project1 "Time to build project1"
+        printfn "Output of building project1 was %s" project1Dll.ExecutableOutput
+        printfn "Project2 directory is %s" (ProjectDirectory project2)
+
+        // Add a new reference project2->project1. There should be no completions because Mary doesn't exist yet.
+        this.AddAssemblyReference(project2,project1Dll.ExecutableOutput)
+        TakeCoffeeBreak(this.VS) // Dependencies between projects get registered for file-watching during OnIdle processing
+        MoveCursorToEndOfMarker(file2,"File1.File1.")
+        let completions = AutoCompleteAtCursor(file2)
+        Assert.AreEqual(0, completions.Length)
+        
+        // Now modify project1's file and rebuild.
+        ReplaceFileInMemory file1 
+                                ["#light"
+                                 "module File1 = "
+                                 "    let Mary x = \"\""]
+        SaveFileToDisk file1      
+        time1 Build project1 "Time to build project1 second time" |> ignore                       
+        TakeCoffeeBreak(this.VS) // Give enough time to catch up             
+        MoveCursorToEndOfMarker(file2,"File1.File1.")
+        TakeCoffeeBreak(this.VS) // Give enough time to catch up             
+        let completions = AutoCompleteAtCursor(file2)
+        Assert.AreNotEqual(0, completions.Length)
+        printfn "Completions=%A\n" completions
+            
+    // In this bug, relative paths to referenced assemblies weren't seen.
+    [<Test>]
+    member public this.``Timestamps.ReferenceAssemblyChangeRelative``() =
+        use _guard = this.UsingNewVS()
+        let solution = this.CreateSolution()
+        let project1 = CreateProject(solution,"testproject1")
+        
+        let MakeRelativePath(path1:string, path2) =
+            // Pretend to return a path to path1 relative to path2.
+            let temp = (System.IO.Path.GetTempPath())
+            let tempLen = temp.Length
+            ".."+(path1.Substring(tempLen-1))
+        
+        let file1 = AddFileFromText(project1,"File1.fs",
+                                    ["#light"]
+                                     )
+        let file1 = OpenFile(project1,"File1.fs")
+        let project2 = CreateProject(solution,"testproject2")
+        let file2 = AddFileFromText(project2,"File2.fs",
+                                    ["#light"
+                                     "File1.File1."
+                                     "()"])
+        let file2 = OpenFile(project2,"File2.fs")
+        
+        // Build project1 which will later have the type being referenced by project2
+        let project1Dll = time1 Build project1 "Time to build project1"
+        printfn "Output of building project1 was %s" project1Dll.ExecutableOutput
+        printfn "Project2 directory is %s" (ProjectDirectory project2)
+        let project1DllRelative = MakeRelativePath(project1Dll.ExecutableOutput, (ProjectDirectory project2))
+        printfn "Relative output of building project1 was %s" project1DllRelative
+        
+        // Add a new reference project2->project1. There should be no completions because Mary doesn't exist yet.
+        this.AddAssemblyReference(project2,project1DllRelative)
+        TakeCoffeeBreak(this.VS) // Dependencies between projects get registered for file-watching during OnIdle processing
+        MoveCursorToEndOfMarker(file2,"File1.File1.")
+        let completions = AutoCompleteAtCursor(file2)
+        Assert.AreEqual(0, completions.Length)
+        
+        // Now modify project1's file and rebuild.
+        ReplaceFileInMemory file1 
+                                ["#light"
+                                 "module File1 = "
+                                 "    let Mary x = \"\""]
+        SaveFileToDisk file1      
+        time1 Build project1 "Time to build project1 second time" |> ignore                       
+        TakeCoffeeBreak(this.VS) // Give enough time to catch up             
+        MoveCursorToEndOfMarker(file2,"File1.File1.")
+        TakeCoffeeBreak(this.VS) // Give enough time to catch up             
+        let completions = AutoCompleteAtCursor(file2)
+        Assert.AreNotEqual(0, completions.Length)
+        printfn "Completions=%A\n" completions         
+        
+
+    // FEATURE: When a referenced project's assembly timestamp changes the reference is reread.
+    [<Test>]
+    [<Category("TakesMoreThanFifteenSeconds")>]
+    member public this.``Timestamps.ProjectReferenceAssemblyChange``() =
+        use _guard = this.UsingNewVS()
+        let solution = this.CreateSolution()
+        let project1 = CreateProject(solution,"testproject1")
+        
+        let file1 = AddFileFromText(project1,"File1.fs",
+                                    ["#light"]
+                                     )
+        let file1 = OpenFile(project1,"File1.fs")
+        let project2 = CreateProject(solution,"testproject2")
+        let file2 = AddFileFromText(project2,"File2.fs",
+                                    ["#light"
+                                     "File1.File1."
+                                     "()"])
+        let file2 = OpenFile(project2,"File2.fs")
+        SetConfigurationAndPlatform(project1, "Debug|AnyCPU")  // maybe due to msbuild bug on dev10, we must set config/platform when building with ProjectReferences
+        SetConfigurationAndPlatform(project2, "Debug|AnyCPU")  // maybe due to msbuild bug on dev10, we must set config/platform when building with ProjectReferences
+        
+        // Build project1 which will later have the type being referenced by project2
+        let project1Dll = time1 Build project1 "Time to build project1"
+        printf "Output of building project1 was %s\n" project1Dll.ExecutableOutput
+        
+        // Add a new reference project2->project1. There should be no completions because Mary doesn't exist yet.
+        //
+        // WARNING: See bug 4434 - when unit testing this actually goes and builds project1!!!!
+        AddProjectReference(project2,project1)
+
+        TakeCoffeeBreak(this.VS) // Dependencies between projects get registered for file-watching during OnIdle processing
+        SetConfigurationAndPlatform(project1, "Debug|AnyCPU")  // maybe due to msbuild bug on dev10, we must set config/platform when building with ProjectReferences
+        SetConfigurationAndPlatform(project2, "Debug|AnyCPU")  // maybe due to msbuild bug on dev10, we must set config/platform when building with ProjectReferences
+        MoveCursorToEndOfMarker(file2,"File1.File1.")
+        let completions = AutoCompleteAtCursor(file2)
+        Assert.AreEqual(0, completions.Length)
+        
+        // Now modify project1's file and rebuild.
+        ReplaceFileInMemory file1 
+                                ["#light"
+                                 "module File1 = "
+                                 "    let Mary x = \"\""]
+        SaveFileToDisk file1   
+        time1 Build project1 "Time to build project1 second time" |> ignore                       
+        TakeCoffeeBreak(this.VS) // Give enough time to catch up             
+        MoveCursorToEndOfMarker(file2,"File1.File1.")
+        TakeCoffeeBreak(this.VS) // Give enough time to catch up             
+        let completions = AutoCompleteAtCursor(file2)
+        Assert.AreNotEqual(0, completions.Length)
+        printfn "Completions=%A\n" completions            
+
+
+//Allow the TimeStampTests run under different context
+namespace UnitTests.Tests.LanguageService.TimeStamp
+open UnitTests.Tests.LanguageService
+open UnitTests.TestLib.LanguageService
+open UnitTests.TestLib.ProjectSystem
+open NUnit.Framework
+open Salsa.Salsa
+
+// context msbuild
+[<TestFixture>] 
+[<Category("LanguageService.MSBuild")>]
+type ``MSBuild`` = 
+   inherit TimeStampTests
+   new() = { inherit TimeStampTests(VsOpts = fst (Models.MSBuild())); }
+
+// Context project system
+[<TestFixture>] 
+[<Category("LanguageService.ProjectSystem")>]
+type ``ProjectSystem`` = 
+    inherit TimeStampTests
+    new() = { inherit TimeStampTests(VsOpts = LanguageServiceExtension.ProjectSystem); } 
\ No newline at end of file
diff --git a/vsintegration/src/unittests/Tests.Powerpack.fs b/vsintegration/src/unittests/Tests.Powerpack.fs
new file mode 100644
index 0000000..89204dd
--- /dev/null
+++ b/vsintegration/src/unittests/Tests.Powerpack.fs
@@ -0,0 +1,88 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+namespace UnitTests.Tests.PowerPack
+
+open NUnit.Framework
+open System
+open System.IO
+open System.Diagnostics
+open Microsoft.FSharp.Build
+open Microsoft.Build.BuildEngine
+open Microsoft.Build.Framework
+open Microsoft.Build.Utilities
+open UnitTests.TestLib.Utils.FilesystemHelpers
+
+[<TestFixture>]
+type FsLexTests() = 
+    
+    [<SetUp>]
+    member this.Setup() = ()
+        
+    [<TearDown>]
+    member this.TearDown() = ()
+        
+    [<Test>]
+    member public this.TestCodePage() =
+        let tool = new Microsoft.FSharp.Build.FsLex()
+        tool.CodePage <- "65001"
+        let cmd = tool.InternalGenerateCommandLineCommands()
+        Assert.AreEqual("--codepage 65001 ", cmd)
+
+    [<Test>]
+    member public this.TestOutputFile() =
+        let tool = new Microsoft.FSharp.Build.FsLex()
+        tool.OutputFile <- "result.fs"
+        let cmd = tool.InternalGenerateCommandLineCommands()
+        Assert.AreEqual("-o result.fs ", cmd)
+
+    [<Test>]
+    member public this.TestUnicode() =
+        let tool = new Microsoft.FSharp.Build.FsLex()
+        tool.Unicode <- true
+        let cmd = tool.InternalGenerateCommandLineCommands()
+        Assert.AreEqual("--unicode ", cmd)
+
+    [<Test>]
+    member public this.TestUnicodeNegCase() =
+        let tool = new Microsoft.FSharp.Build.FsLex()
+        tool.Unicode <- false
+        let cmd = tool.InternalGenerateCommandLineCommands()
+        // Verify Unicode flag not specified
+        Assert.AreEqual("", cmd)
+
+[<TestFixture>]
+type FsYaccTests() = 
+    
+    [<SetUp>]
+    member this.Setup() = ()
+        
+    [<TearDown>]
+    member this.TearDown() = ()
+        
+    [<Test>]
+    member public this.TestCodePage() =
+        let tool = new Microsoft.FSharp.Build.FsYacc()
+        tool.CodePage <- "65001"
+        let cmd = tool.InternalGenerateCommandLineCommands()
+        Assert.AreEqual("--codepage 65001", cmd)
+
+    [<Test>]
+    member public this.TestOutputFile() =
+        let tool = new Microsoft.FSharp.Build.FsYacc()
+        tool.OutputFile <- "result.fs"
+        let cmd = tool.InternalGenerateCommandLineCommands()
+        Assert.AreEqual("-o result.fs", cmd)
+
+    [<Test>]
+    member public this.TestMLCompatibility() =
+        let tool = new Microsoft.FSharp.Build.FsYacc()
+        tool.MLCompatibility <- true
+        let cmd = tool.InternalGenerateCommandLineCommands()
+        Assert.AreEqual("--ml-compatibility", cmd)
+        
+    [<Test>]
+    member public this.TestMLCompatibilityFalse() =
+        let tool = new Microsoft.FSharp.Build.FsYacc()
+        tool.MLCompatibility <- false
+        let cmd = tool.InternalGenerateCommandLineCommands()
+        Assert.AreEqual("", cmd)
\ No newline at end of file
diff --git a/vsintegration/src/unittests/Tests.ProjectSystem.Configs.fs b/vsintegration/src/unittests/Tests.ProjectSystem.Configs.fs
new file mode 100644
index 0000000..2ef7ac3
--- /dev/null
+++ b/vsintegration/src/unittests/Tests.ProjectSystem.Configs.fs
@@ -0,0 +1,212 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+namespace UnitTests.Tests.ProjectSystem
+
+// System namespaces
+open System
+open System.Collections.Generic
+open System.IO
+open System.Text.RegularExpressions
+open System.Xml.Linq
+open NUnit.Framework
+
+// VS namespaces 
+open Microsoft.VisualStudio.Shell.Interop
+open Microsoft.VisualStudio.FSharp.ProjectSystem
+
+// Internal unittest namespaces
+open Salsa
+open UnitTests.TestLib.Utils.Asserts
+open UnitTests.TestLib.Utils.FilesystemHelpers
+open UnitTests.TestLib.ProjectSystem
+
+
+[<TestFixture>]
+type Config() = 
+    inherit TheTests()
+
+    /////////////////////////////////
+    // project helpers
+    static let SaveProject(project : UnitTestingFSharpProjectNode) =
+        project.Save(null, 1, 0u) |> ignore
+
+    [<Test>]
+    member this.TargetPlatform () =
+        this.MakeProjectAndDoWithProjectFileAndConfigChangeNotifier(["foo.fs"], [], 
+            this.MSBuildProjectMulitplatBoilerplate "Library",  
+            (fun project ccn projFileName ->
+                ccn((project :> IVsHierarchy), "Debug|x86")
+                project.ComputeSourcesAndFlags()
+                let flags = project.GetCompileFlags() |> List.ofArray
+                Assert.IsTrue(List.exists (fun s -> s = "--platform:x86") flags)
+                ()
+        ))
+
+    [<Test>]
+    member this.``Configs.EnsureAtLeastOneConfiguration`` () =
+        this.HelperEnsureAtLeastOne 
+            @"<PropertyGroup Condition="" '$(Platform)' == 'x86' "" />" 
+            [|"Debug"|]  // the goal of the test - when no configs, "Debug" should magically appear
+            [|"x86"|]
+
+    [<Test>]
+    member this.``Configs.EnsureAtLeastOnePlatform`` () =
+        this.HelperEnsureAtLeastOne 
+            @"<PropertyGroup Condition="" '$(Configuration)' == 'Release' "" />"
+            [|"Release"|]
+            [|"Any CPU"|] // the goal of the test - when no platforms, "AnyCPU" should magically appear
+
+    [<Test>]
+    member this.``Configs.EnsureAtLeastOneConfigurationAndPlatform`` () =
+        this.HelperEnsureAtLeastOne 
+            ""
+            [|"Debug"|] // first goal of the test - when no configs, "Debug" should magically appear
+            [|"Any CPU"|] // second goal of the test - when no platforms, "AnyCPU" should magically appear
+
+    [<Test>]
+    member this.``Configs.EnsureAtLeastOneConfiguration.Imported`` () =
+        // Take advantage of the fact that we always create projects one directory below TempPath
+        let tmpTargets = Path.Combine(Path.GetTempPath(), "foo.targets")
+        try
+            File.AppendAllText(tmpTargets,
+                @"<Project ToolsVersion='4.0' DefaultTargets='Build' xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
+                    <PropertyGroup Condition="" '$(Platform)' == 'x86' "" />
+                  </Project>")
+
+            this.HelperEnsureAtLeastOne 
+                @"<Import Project=""..\foo.targets"" />"
+                [|"Debug"|]  // the goal of the test - when no configs, "Debug" should magically appear
+                [|"x86"|]
+        finally
+            File.Delete tmpTargets
+
+    [<Test>]
+    member this.``Configs.EnsureAtLeastOnePlatform.Imported`` () =
+        // Take advantage of the fact that we always create projects one directory below TempPath
+        // The unit test failed due to the previous test use the same target name "foo.targets". 
+        // The vs record the platform config "x86", so the next test failed for the unexpected platform.
+        let tmpTargets = Path.Combine(Path.GetTempPath(), "foo2.targets")
+        try
+            File.AppendAllText(tmpTargets,
+                @"<Project ToolsVersion='4.0' DefaultTargets='Build' xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
+                    <PropertyGroup Condition="" '$(Configuration)' == 'Release' "" />
+                  </Project>")
+            this.HelperEnsureAtLeastOne 
+                @"<Import Project=""..\foo2.targets"" />"
+                [|"Release"|]
+                [|"Any CPU"|] // the goal of the test - when no platforms, "AnyCPU" should magically appear
+        finally
+            File.Delete tmpTargets
+    
+    [<Test>]
+    member this.``Configs.Renaming`` () =
+        this.MakeProjectAndDoWithProjectFile(["foo.fs"], [],
+            this.MSBuildProjectMultiConfigBoilerplate ["Debug",""; "Release",""],
+            (fun project projFileName ->
+                this.CheckConfigNames(project, [|"Debug"; "Release"|])
+                project.ConfigProvider.RenameCfgsOfCfgName("Debug", "Buggy") |> AssertEqual VSConstants.S_OK
+                this.CheckConfigNames(project, [|"Buggy";"Release"|])
+                SaveProject(project)
+                let fsprojFileText = File.ReadAllText(projFileName)
+                let xDoc = XDocument.Load(new StringReader(fsprojFileText))
+                let expected = this.MSBuildProjectMultiConfigBoilerplate ["Buggy",""; "Release",""]
+                let expectedXDoc = XDocument.Load(new StringReader(TheTests.SimpleFsprojText(["foo.fs"],[],expected)))
+                TheTests.AssertSimilarXml(expectedXDoc.Root, xDoc.Root)                
+            ))
+            
+    [<Test>]
+    member this.``Configs.Deleting`` () =
+        this.MakeProjectAndDoWithProjectFile(["foo.fs"], [],
+            this.MSBuildProjectMultiConfigBoilerplate ["Debug",""; "Release",""],
+            (fun project projFileName ->
+                this.CheckConfigNames(project, [|"Debug";"Release"|])
+                project.ConfigProvider.DeleteCfgsOfCfgName("Debug") |> AssertEqual VSConstants.S_OK
+                this.CheckConfigNames(project, [|"Release"|])
+                SaveProject(project)
+                let fsprojFileText = File.ReadAllText(projFileName)
+                let xDoc = XDocument.Load(new StringReader(fsprojFileText))
+                let expected = this.MSBuildProjectMultiConfigBoilerplate ["Release",""]
+                let expectedXDoc = XDocument.Load(new StringReader(TheTests.SimpleFsprojText(["foo.fs"],[],expected)))
+                TheTests.AssertSimilarXml(expectedXDoc.Root, xDoc.Root)                
+            ))
+    [<Test>]
+    member this.``Configs.Adding`` () =
+        this.MakeProjectAndDoWithProjectFile(["foo.fs"], [],
+            this.MSBuildProjectMultiConfigBoilerplate ["Debug","<Foo/>"; "Release",""],
+            (fun project projFileName ->    
+                this.CheckConfigNames(project, [|"Debug";"Release"|])
+                project.ConfigProvider.AddCfgsOfCfgName("Buzz", "Debug", 0) |> AssertEqual VSConstants.S_OK
+                this.CheckConfigNames(project, [|"Debug";"Release";"Buzz"|])
+                SaveProject(project)
+                let fsprojFileText = File.ReadAllText(projFileName)
+                let xDoc = XDocument.Load(new StringReader(fsprojFileText))
+                let expected = this.MSBuildProjectMultiConfigBoilerplate ["Debug","<Foo/>"; "Release",""; "Buzz","<Foo/>"]
+                let expectedXDoc = XDocument.Load(new StringReader(TheTests.SimpleFsprojText(["foo.fs"],[],expected)))
+                TheTests.AssertSimilarXml(expectedXDoc.Root, xDoc.Root)                
+            ))
+    [<Test>]
+    member this.``Configs.AddingBaseless`` () =
+        this.MakeProjectAndDoWithProjectFile(["foo.fs"], [],
+            this.MSBuildProjectMultiConfigBoilerplate ["Debug","<Foo/>"; "Release",""],
+            (fun project projFileName ->
+                this.CheckConfigNames(project, [|"Debug";"Release"|])
+                project.ConfigProvider.AddCfgsOfCfgName("Buzz", null, 0) |> AssertEqual VSConstants.S_OK
+                this.CheckConfigNames(project, [|"Debug";"Release";"Buzz"|])
+                SaveProject(project)
+                let fsprojFileText = File.ReadAllText(projFileName)
+                let xDoc = XDocument.Load(new StringReader(fsprojFileText))
+                let expected = this.MSBuildProjectMultiConfigBoilerplate ["Debug","<Foo/>"; "Release",""; "Buzz",""]
+                let expectedXDoc = XDocument.Load(new StringReader(TheTests.SimpleFsprojText(["foo.fs"],[],expected)))
+                TheTests.AssertSimilarXml(expectedXDoc.Root, xDoc.Root)                
+            ))
+
+    [<Test>]
+    member this.``Configs.Platforms.Deleting`` () =
+        this.MakeProjectAndDoWithProjectFile(["foo.fs"], [],
+            this.MSBuildProjectMultiPlatform ["Any CPU",""; "x86",""],
+            (fun project projFileName ->
+                this.CheckPlatformNames(project, [|"Any CPU";"x86"|])
+                project.ConfigProvider.DeleteCfgsOfPlatformName("Any CPU") |> AssertEqual VSConstants.S_OK
+                this.CheckPlatformNames(project, [|"x86"|])
+                SaveProject(project)
+                let fsprojFileText = File.ReadAllText(projFileName)
+                let xDoc = XDocument.Load(new StringReader(fsprojFileText))
+                let expected = this.MSBuildProjectMultiPlatform ["x86",""]
+                let expectedXDoc = XDocument.Load(new StringReader(TheTests.SimpleFsprojText(["foo.fs"],[],expected)))
+                TheTests.AssertSimilarXml(expectedXDoc.Root, xDoc.Root)                
+
+        ))
+        
+    [<Test>]
+    member this.``Configs.Platforms.Adding`` () =
+        this.MakeProjectAndDoWithProjectFile(["foo.fs"], [],
+            this.MSBuildProjectMultiPlatform ["Any CPU",""; "x86","<Custom/>"],
+            (fun project projFileName ->
+                this.CheckPlatformNames(project, [|"Any CPU";"x86"|])
+                project.ConfigProvider.AddCfgsOfPlatformName("x64", "x86") |> AssertEqual VSConstants.S_OK
+                this.CheckPlatformNames(project, [|"Any CPU";"x86";"x64"|])
+                SaveProject(project)
+                let fsprojFileText = File.ReadAllText(projFileName)
+                let xDoc = XDocument.Load(new StringReader(fsprojFileText))
+                let expected = this.MSBuildProjectMultiPlatform ["Any CPU",""; "x86","<Custom/>"; "x64","<Custom/>"]
+                let expectedXDoc = XDocument.Load(new StringReader(TheTests.SimpleFsprojText(["foo.fs"],[],expected)))
+                TheTests.AssertSimilarXml(expectedXDoc.Root, xDoc.Root)                
+
+        ))
+
+    [<Test>]
+    member this.``Configs.Platforms.AddingBaseless`` () =
+        this.MakeProjectAndDoWithProjectFile(["foo.fs"], [],
+            this.MSBuildProjectMultiPlatform ["Any CPU",""; "x86",""],
+            (fun project projFileName ->
+                this.CheckPlatformNames(project, [|"Any CPU";"x86"|])
+                project.ConfigProvider.AddCfgsOfPlatformName("x64", null) |> AssertEqual VSConstants.S_OK
+                this.CheckPlatformNames(project, [|"Any CPU";"x86";"x64"|])
+                SaveProject(project)
+                let fsprojFileText = File.ReadAllText(projFileName)
+                let xDoc = XDocument.Load(new StringReader(fsprojFileText))
+                let expected = this.MSBuildProjectMultiPlatform ["Any CPU",""; "x86",""; "x64",""]
+                let expectedXDoc = XDocument.Load(new StringReader(TheTests.SimpleFsprojText(["foo.fs"],[],expected)))
+                TheTests.AssertSimilarXml(expectedXDoc.Root, xDoc.Root)                
+
+        ))
diff --git a/vsintegration/src/unittests/Tests.ProjectSystem.Miscellaneous.fs b/vsintegration/src/unittests/Tests.ProjectSystem.Miscellaneous.fs
new file mode 100644
index 0000000..f6902cf
--- /dev/null
+++ b/vsintegration/src/unittests/Tests.ProjectSystem.Miscellaneous.fs
@@ -0,0 +1,839 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+namespace UnitTests.Tests.ProjectSystem
+
+// System namespaces
+open System
+open System.Collections.Generic
+open System.Globalization
+open System.IO
+open System.Text
+open System.Text.RegularExpressions
+
+// VS namespaces 
+open Microsoft.VisualStudio.Shell
+open Microsoft.VisualStudio.Shell.Interop
+open Microsoft.VisualStudio.FSharp.ProjectSystem
+
+// Internal unittest namespaces
+open NUnit.Framework
+open Salsa
+open UnitTests.TestLib.Utils.Asserts
+open UnitTests.TestLib.Utils.FilesystemHelpers
+open UnitTests.TestLib.ProjectSystem
+
+[<TestFixture>]
+type Miscellaneous() = 
+    inherit TheTests()
+
+    //TODO: look for a way to remove the helper functions
+    /////////////////////////////////
+    // project helpers
+    static let SaveProject(project : UnitTestingFSharpProjectNode) =
+        project.Save(null, 1, 0u) |> ignore
+
+    //[<Test>]   // keep disabled unless trying to prove that UnhandledExceptionHandler is working 
+    member public this.EnsureThatUnhandledExceptionsCauseAnAssert() =
+        this.MakeProjectAndDo([], ["System"], "", (fun proj ->
+            let t = new System.Threading.Thread(new System.Threading.ThreadStart(fun () -> failwith "foo"))
+            t.Start()
+            System.Threading.Thread.Sleep(1000)
+        ))
+
+    [<Test>]
+    member public this.``Miscellaneous.CreatePropertiesObject`` () =
+        DoWithTempFile "Test.fsproj" (fun projFile ->
+            File.AppendAllText(projFile, TheTests.SimpleFsprojText([], [], ""))
+            use project = TheTests.CreateProject(projFile) 
+            let prop = project.CreatePropertiesObject()
+            Assert.AreEqual(typeof<FSharpProjectNodeProperties>, prop.GetType())
+            )
+            
+    [<Test>]
+    member public this.``Miscellaneous.TestProperties`` () =
+        DoWithTempFile "Test.fsproj" (fun projFile ->
+            File.AppendAllText(projFile, TheTests.SimpleFsprojText([], [], ""))
+            use project = TheTests.CreateProject(projFile) 
+            let prop = new FSharpProjectNodeProperties(project)
+            
+            prop.AssemblyName <- "a"
+            Assert.AreEqual("a", prop.AssemblyName)            
+            
+            // Output type and output file name
+            prop.OutputType <- OutputType.Exe
+            Assert.AreEqual(OutputType.Exe, prop.OutputType)
+            Assert.AreEqual("a.exe", prop.OutputFileName)
+            
+            prop.OutputType <- OutputType.Library
+            Assert.AreEqual(OutputType.Library, prop.OutputType)
+            Assert.AreEqual("a.dll", prop.OutputFileName)
+            
+            prop.OutputType <- OutputType.WinExe
+            Assert.AreEqual(OutputType.WinExe, prop.OutputType)
+            Assert.AreEqual("a.exe", prop.OutputFileName)
+            )            
+            
+    [<Test>]
+    member public this.``Miscellaneous.CreateServices`` () =
+        DoWithTempFile "Test.fsproj" (fun projFile ->
+            File.AppendAllText(projFile, TheTests.SimpleFsprojText([], [], ""))
+            use project = TheTests.CreateProject(projFile) 
+            let proj = project.CreateServices(typeof<VSLangProj.VSProject>)
+            Assert.AreEqual(typeof<Microsoft.VisualStudio.FSharp.ProjectSystem.Automation.OAVSProject>, proj.GetType())
+            let eproj = project.CreateServices(typeof<EnvDTE.Project>)
+            Assert.AreEqual(typeof<Microsoft.VisualStudio.FSharp.ProjectSystem.Automation.OAProject>, eproj.GetType())
+            let badservice = project.CreateServices(typeof<string>)
+            Assert.IsNull(badservice)
+            )
+            
+    [<Test>]
+    member public this.``Miscellaneous.FSharpFileNode.GetRelativePath`` () =
+        this.MakeProjectAndDo(["orig1.fs"], [], "", (fun project ->
+            let absFilePath = Path.Combine(project.ProjectFolder, "orig1.fs")
+            let files = new List<FSharpFileNode>()
+            project.FindNodesOfType(files)
+            Assert.AreEqual(1, files.Count)
+            let file = files.[0]
+            let path = file.GetRelativePath()
+            Assert.AreEqual("orig1.fs", path)
+            ))
+           
+    [<Test>]
+    member public this.``Miscellaneous.FSharpFileNode.CreateServices`` () =
+        this.MakeProjectAndDo(["orig1.fs"], [], "", (fun project ->
+            let absFilePath = Path.Combine(project.ProjectFolder, "orig1.fs")
+            let files = new List<FSharpFileNode>()
+            project.FindNodesOfType(files)
+            Assert.AreEqual(1, files.Count)
+            let file = files.[0]
+            let badservice = file.CreateServices(typeof<string>)
+            Assert.IsNull(badservice)
+            let eproj = file.CreateServices(typeof<EnvDTE.ProjectItem>)
+            Assert.AreEqual(typeof<Microsoft.VisualStudio.FSharp.ProjectSystem.Automation.OAFileItem>, eproj.GetType())
+            ))
+
+    
+    //[<Test>]    
+    member public this.AttemptDragAndDrop() =
+        printfn "starting..."
+        let fsproj = "D:\Depot\staging\Test.fsproj"
+        printfn "here1"
+        let buildEngine = Utilities.InitializeMsBuildEngine(null)
+        printfn "here2"
+        let buildProject = Utilities.InitializeMsBuildProject(buildEngine, fsproj)
+        printfn "here3"
+        let package = new FSharpProjectPackage()
+        let project = new UnitTestingFSharpProjectNode(package)
+        //let dte = Package.GetGlobalService(typeof<EnvDTE.DTE>)
+        //let dte = System.Runtime.InteropServices.Marshal.GetActiveObject("VisualStudio.DTE.8.0") :?> EnvDTE80.DTE2
+        //let dteServiceProvider = dte :?> Microsoft.VisualStudio.OLE.Interop.IServiceProvider
+        //project.SetSite(dteServiceProvider) |> ignore
+        let ivstrk = (new ServiceProvider(VsMocks.mockServiceProvider)).GetService(typeof<SVsTrackProjectDocuments>) :?> IVsTrackProjectDocuments2
+        printfn "%A" ivstrk
+        project.SetSite(VsMocks.mockServiceProvider) |> ignore
+        printfn "here4"
+        project.BuildProject <- buildProject
+        let mutable cancelled = 0
+        let mutable guid = Guid.NewGuid()
+        printfn "about to load .fsproj"
+        project.Load(fsproj, null, null, 2u, &guid, &cancelled)
+        printfn "loaded"
+        let mutable dwEffect = 0u
+        let mutable iOleDataObject = null
+        let mutable iDropSource = null
+        project.GetDropInfo(&dwEffect, &iOleDataObject, &iDropSource) |> ValidateOK
+        // REVIEW validate dwEffect
+        let mutable keyboardState = 1u
+        let mutable node = project.FirstChild
+        let mutable finished = false
+        printfn "find file..."
+        while not finished do
+            match node with
+            | :? FSharpFileNode as fileNode ->
+                printfn "file %s" fileNode.FileName 
+                if fileNode.FileName = "aaa.fs" then
+                    finished <- true
+            | _ ->
+                node <- node.NextSibling 
+                if node = null then
+                    finished <- true
+        Assert.AreNotEqual(node, null)
+        let itemId = node.ID
+        
+        project.DragEnter(iOleDataObject, keyboardState, itemId, &dwEffect) |> ignore
+        ()
+
+    
+    [<Test>]
+    member public this.``Automation.OutputGroup.OUTPUTLOC``() =
+        this.MakeProjectAndDoWithProjectFile(["foo.fs"], [],
+            this.MSBuildProjectMultiPlatform(["x86",""],"x86"),
+            (fun project projFileName ->
+                let prjCfg = project.ConfigProvider.GetProjectConfiguration(new ConfigCanonicalName("Debug", "x86")) :> IVsProjectCfg2
+                let mutable outputGroup : IVsOutputGroup = null
+                prjCfg.OpenOutputGroup("Built", &outputGroup) |> ValidateOK
+                let mutable keyOutput : IVsOutput2 = null
+                (outputGroup :?> IVsOutputGroup2).get_KeyOutputObject(&keyOutput) |> ValidateOK
+                let mutable value : obj = null
+                keyOutput.get_Property("OUTPUTLOC", &value) |> ValidateOK
+                let expectedOutput = (projFileName |> Path.GetDirectoryName) + @"\bin\Debug\Blah.dll"
+                AssertEqual expectedOutput (value :?> string)
+            )
+         )
+
+    [<Test>]
+    member public this.``Automation.OutputGroups``() =
+        DoWithTempFile "Test.fsproj" (fun file ->
+            let text = TheTests.FsprojTextWithProjectReferences([],[],[],@"
+                <PropertyGroup>
+                    <DocumentationFile>Out.xml</DocumentationFile>
+                </PropertyGroup>
+                <ItemGroup>
+                    <Compile Include=""foo.fs"" />
+                    <EmbeddedResource Include=""Blah.resx"" />
+                    <Content Include=""Yadda.txt"" />
+                </ItemGroup>")
+            File.AppendAllText(file, text)
+            let dirName = Path.GetDirectoryName(file)
+            let sp, cnn = VsMocks.MakeMockServiceProviderAndConfigChangeNotifier()
+            let project = TheTests.CreateProject(file, "false", cnn, sp)            
+            use project = project
+            let prjCfg = project.ConfigProvider.GetProjectConfiguration(new ConfigCanonicalName("Debug","AnyCPU")) :> IVsProjectCfg2
+            let count = [| 0u |]
+            prjCfg.get_OutputGroups(0u, null, count) |> ValidateOK
+            let ogs : array<IVsOutputGroup> = Array.create (int count.[0]) null
+            prjCfg.get_OutputGroups(count.[0], ogs, count)  |> ValidateOK
+            let ogs : array<IVsOutputGroup2> = ogs |> Array.map (fun x -> downcast x)
+            let ogInfos = 
+                [for og in ogs do
+                    let mutable canonicalName = ""
+                    og.get_CanonicalName(&canonicalName) |> ValidateOK
+                    let mutable description = ""
+                    og.get_Description(&description) |> ValidateOK 
+                    let mutable displayName = ""
+                    og.get_DisplayName(&displayName) |> ValidateOK 
+                    let mutable keyOutput = ""
+                    let keyOutputResult = og.get_KeyOutput(&keyOutput)
+                    let count = [| 0u |]
+                    og.get_Outputs(0u, null, count) |> ValidateOK 
+                    let os : array<IVsOutput2> = Array.create (int count.[0]) null
+                    og.get_Outputs(count.[0], os, count) |> ValidateOK 
+                    yield canonicalName, description, displayName, keyOutput, keyOutputResult, [
+                        for o in os do
+                            let mutable canonicalName = ""
+                            o.get_CanonicalName(&canonicalName) |> ValidateOK 
+                            let mutable url = ""
+                            o.get_DeploySourceURL(&url) |> ValidateOK 
+                            let mutable displayName = ""
+                            o.get_DisplayName(&displayName) |> ValidateOK 
+                            let mutable relativeUrl = ""
+                            o.get_RootRelativeURL(&relativeUrl) |> ValidateOK
+                            yield canonicalName, url, displayName, relativeUrl]
+                ]
+            let expected =
+                ["Built", "Contains the DLL or EXE built by the project.", "Primary Output", dirName+ @"\obj\Debug\Test.exe", 0, [dirName+ @"\obj\Debug\Test.exe", "file:///"+dirName+ @"\obj\Debug\Test.exe", dirName+ @"\obj\Debug\Test.exe", "Test.exe"]
+                 "ContentFiles", "Contains all content files in the project.", "Content Files", "", 1, [dirName+ @"\Yadda.txt", "file:///"+dirName+ @"\Yadda.txt", dirName+ @"\Yadda.txt", "Yadda.txt"]
+                 "LocalizedResourceDlls", "Contains the satellite assemblies for each culture's resources.", "Localized Resources", "", 1, []
+                 "Documentation", "Contains the XML Documentation files for the project.", "Documentation Files", dirName+ @"\Out.xml", 0, [dirName+ @"\Out.xml", "file:///"+dirName+ @"\Out.xml", dirName+ @"\Out.xml", "Out.xml"]
+                 "Symbols", "Contains the debugging files for the project.", "Debug Symbols", "", 1, [dirName+ @"\obj\Debug\Test.pdb", "file:///"+dirName+ @"\obj\Debug\Test.pdb", dirName+ @"\obj\Debug\Test.pdb", "Test.pdb"]
+                 "SourceFiles", "Contains all source files in the project.", "Source Files", "", 1, [dirName+ @"\foo.fs", "file:///"+dirName+ @"\foo.fs", dirName+ @"\foo.fs", "foo.fs"
+                                                                                                     dirName+ @"\Blah.resx", "file:///"+dirName+ @"\Blah.resx", dirName+ @"\Blah.resx", "Blah.resx"
+                                                                                                     dirName+ @"\Test.fsproj", "file:///"+dirName+ @"\Test.fsproj", dirName+ @"\Test.fsproj", "Test.fsproj"]
+                 "XmlSerializer", "Contains the XML serialization assemblies for the project.", "XML Serialization Assemblies", "", 1, []]
+            AssertEqual expected ogInfos
+        )
+
+    [<Test>]
+    member public this.``LoadProject.x86`` () =
+        this.MakeProjectAndDoWithProjectFile(["foo.fs"], ["System"],
+            this.MSBuildProjectMultiPlatform(["x86",""],"x86"),
+            (fun project projFileName ->
+                this.CheckPlatformNames(project, [|"x86"|])
+                let refContainer =
+                    let l = new List<ReferenceContainerNode>()
+                    project.FindNodesOfType(l)
+                    l.[0]
+                let l = new List<AssemblyReferenceNode>()
+                refContainer.FindNodesOfType<AssemblyReferenceNode>(l)
+                AssertEqual 1 l.Count
+        ))
+
+    [<Test>]
+    member public this.``BuildAndClean``() =
+        this.MakeProjectAndDoWithProjectFileAndConfigChangeNotifier(["foo.fs"], [], 
+             this.MSBuildProjectBoilerplate "Library", 
+             (fun project ccn projFileName ->
+                let fooPath = Path.Combine(project.ProjectFolder, "foo.fs")
+                File.AppendAllText(fooPath, "#light")
+                File.AppendAllText(fooPath, "module Foo")
+                
+                //ccn((project :> IVsHierarchy), "Debug|Any CPU")
+                let configName = "Debug"                
+                let (hr, configurationInterface) = project.ConfigProvider.GetCfgOfName(configName, ProjectConfig.Any_CPU)
+                AssertEqual VSConstants.S_OK hr
+                let config = configurationInterface :?> ProjectConfig
+                let (hr, vsBuildableCfg) = config.get_BuildableProjectCfg()
+                let buildableCfg = vsBuildableCfg :?> BuildableProjectConfig
+                AssertEqual VSConstants.S_OK hr
+                
+                let success = ref false
+                use event = new System.Threading.ManualResetEvent(false)
+                let (hr, cookie) = 
+                    buildableCfg.AdviseBuildStatusCallback(
+                        { new IVsBuildStatusCallback with
+                            member this.BuildBegin pfContinue = pfContinue <- 1; VSConstants.S_OK
+                            member this.BuildEnd fSuccess =
+                                success := fSuccess <> 0
+                                event.Set() |> Assert.IsTrue
+                                VSConstants.S_OK
+                            member this.Tick pfContinue = pfContinue <- 1; VSConstants.S_OK
+                        }
+                    )
+                try
+                    let buildMgrAccessor = project.Site.GetService(typeof<SVsBuildManagerAccessor>) :?> IVsBuildManagerAccessor
+                    let output = VsMocks.vsOutputWindowPane(ref [])
+                    let doBuild target =
+                        success := false
+                        event.Reset() |> Assert.IsTrue
+                        buildMgrAccessor.BeginDesignTimeBuild() |> ValidateOK // this is not a design-time build, but our mock does all the right initialization of the build manager for us, similar to what the system would do in VS for real
+                        buildableCfg.Build(0u, output, target)
+                        event.WaitOne() |> Assert.IsTrue
+                        buildMgrAccessor.EndDesignTimeBuild() |> ValidateOK // this is not a design-time build, but our mock does all the right initialization of the build manager for us, similar to what the system would do in VS for real
+                        AssertEqual true !success    
+                    printfn "building..."
+                    doBuild "Build"                    
+                    AssertEqual true (File.Exists (Path.Combine(project.ProjectFolder, "bin\\Debug\\Blah.dll")))
+                    
+                    printfn "cleaning..."
+                    doBuild "Clean"
+                    AssertEqual false (File.Exists (Path.Combine(project.ProjectFolder, "bin\\Debug\\Blah.dll")))
+                finally
+                    buildableCfg.UnadviseBuildStatusCallback(cookie) |> AssertEqual VSConstants.S_OK
+        ))
+        
+        
+    [<Test>]
+    member public this.``ErrorReporting.EmptyModuleReportedAtTheLastLine``() =
+        let (outputWindowPaneErrors : string list ref) = ref [] // output window pane errors
+        let vso = VsMocks.vsOutputWindowPane(outputWindowPaneErrors)
+        let compileItem = ["foo.fs"]
+        let expectedError = "foo.fs(4,1): warning FS0988: Main module of program is empty: nothing will happen when it is run" // expected error
+
+        // Compile & verify error range
+        DoWithTempFile "Test.fsproj" (fun projFile ->
+            File.AppendAllText(projFile, TheTests.SimpleFsprojText(compileItem, [], ""))
+            use project = TheTests.CreateProject(projFile)
+            let srcFile = (Path.GetDirectoryName projFile) + "\\" + "foo.fs"
+            File.AppendAllText(srcFile, "#light\nlet foo () =\n  printfn \"A\"\n") 
+            project.BuildToOutput("Build", vso) |> ignore // Build the project using vso as the output logger
+            let errors = List.filter (fun (s:string) -> s.Contains(expectedError)) !outputWindowPaneErrors    
+            AssertEqual 1 (List.length errors)
+        )        
+                
+        
+    [<Test>][<ExpectedException (typeof<ClassLibraryCannotBeStartedDirectlyException>)>]
+    member public this.``DebuggingDLLFails``() =
+        this.MakeProjectAndDoWithProjectFileAndConfigChangeNotifier(["foo.fs"], [], 
+            this.MSBuildProjectBoilerplate "Library",  
+            (fun project ccn projFileName ->
+                ccn((project :> IVsHierarchy), "Debug|Any CPU")
+                let fooPath = Path.Combine(project.ProjectFolder, "foo.fs")
+                File.AppendAllText(fooPath, "#light")                
+                let mutable configurationInterface : IVsCfg = null
+                let hr = project.ConfigProvider.GetCfgOfName("Debug", "Any CPU", &configurationInterface)
+                AssertEqual VSConstants.S_OK hr                
+                let config = configurationInterface :?> ProjectConfig
+                config.DebugLaunch(0ul) |> ignore
+                ()
+        ))
+    
+    [<Test>]    
+    member public this.``DebuggingEXESucceeds``() =
+        this.MakeProjectAndDoWithProjectFileAndConfigChangeNotifier(["foo.fs"], [], 
+            this.MSBuildProjectBoilerplate "Exe",  
+            (fun project ccn projFileName ->
+                ccn((project :> IVsHierarchy), "Debug|Any CPU")
+                let fooPath = Path.Combine(project.ProjectFolder, "foo.fs")
+                File.AppendAllText(fooPath, "#light")                
+                let buildResult = project.Build("Build")
+                Assert.IsTrue buildResult.IsSuccessful
+                AssertEqual true (File.Exists (Path.Combine(project.ProjectFolder, "bin\\Debug\\Blah.exe")))
+
+                let mutable configurationInterface : IVsCfg = null
+                let hr = project.ConfigProvider.GetCfgOfName("Debug", "Any CPU", &configurationInterface)
+                AssertEqual VSConstants.S_OK hr
+                let config = configurationInterface :?> ProjectConfig
+                try
+                    config.DebugLaunch(0ul) |> ignore
+                with
+                | :? ClassLibraryCannotBeStartedDirectlyException -> Assert.Fail("Exe should be debuggable")
+                | _ -> Assert.Fail() // DmiLom: Currently DebugLaunch() swallows most exceptions, in future if we improve DebugLaunch() we will expect it to throw a particular exception here
+                ()
+        ))
+        
+    [<Test>]
+    member public this.``IsDocumentInProject`` () =
+        DoWithTempFile "Test.fsproj" (fun file ->
+            let fakeCsLibProjectFile = @"..\CsLib\CsLib.csproj"            
+            File.AppendAllText(file, TheTests.FsprojTextWithProjectReferences(["foo.fs"; @"bar\baz.fs"],["System.dll";"Foo.Bar.Baz.dll"],[fakeCsLibProjectFile],""))
+            let sp, cnn = VsMocks.MakeMockServiceProviderAndConfigChangeNotifier()
+            let project = TheTests.CreateProject(file, "false", cnn, sp)            
+            use project = project
+            let checkInProject shouldBeInProject relPath  =
+                let mkDoc = Path.Combine(project.ProjectFolder, relPath)
+                let priority = [|VSDOCUMENTPRIORITY.DP_Unsupported|]
+                let mutable found = 0
+                let mutable itemId = 0ul
+                let hr,_ = project.IsDocumentInProject(mkDoc, &found, priority)
+                AssertEqual VSConstants.S_OK hr
+                AssertEqual shouldBeInProject (found <> 0)
+            checkInProject true "foo.fs"
+            checkInProject true @"bar\baz.fs"
+            checkInProject false "abracadabra.fs"
+            checkInProject false fakeCsLibProjectFile
+            checkInProject false "System.dll"
+        )
+
+    [<Test>]
+    member public this.``PreBuildEvent`` () =
+        this.MakeProjectAndDoWithProjectFile(["foo.fs"], ["System"], "",
+            (fun project projFileName ->
+                project.SetOrCreateBuildEventProperty("PreBuildEvent", "echo ProjectExt[$(ProjectExt)]")  // just test one example property
+                SaveProject(project)
+                // ensure that <PreBuildEvent> is after <Import> declaration
+                let fsprojFileText = File.ReadAllText(projFileName)
+                printfn "%s" fsprojFileText
+                let regexStr = "<Import Project=.*?Microsoft.FSharp.targets(.|\\n)*?<PreBuildEvent>"
+                TheTests.HelpfulAssertMatches '<' regexStr fsprojFileText
+                // ensure it runs
+                let outputWindowPaneErrors : string list ref = ref [] 
+                let vso = VsMocks.vsOutputWindowPane(outputWindowPaneErrors)
+                let srcFile = (Path.GetDirectoryName projFileName) + "\\" + "foo.fs"
+                File.AppendAllText(srcFile, "let x = 5\n") 
+                project.BuildToOutput("Build", vso) |> ignore // Build the project using vso as the output logger
+                printfn "Build output:"
+                !outputWindowPaneErrors |> Seq.iter (printfn "%s")
+                let expectedRegex = new Regex("\\s*ProjectExt\\[.fsproj\\]")                
+                Assert.IsTrue(!outputWindowPaneErrors |> List.exists (fun s -> expectedRegex.IsMatch(s)), "did not see expected value in build output")
+            ))
+        
+    [<Test>]
+    member public this.``BuildMacroValues`` () = 
+        DoWithTempFile "MyAssembly.fsproj" (fun file ->
+            File.AppendAllText(file, TheTests.FsprojTextWithProjectReferences([],[],[],""))
+            let sp, cnn = VsMocks.MakeMockServiceProviderAndConfigChangeNotifier()
+            use project = TheTests.CreateProject(file, "false", cnn, sp) 
+            let targetPath = project.GetBuildMacroValue("TargetPath")
+            let expectedTargetPath = Path.Combine(Path.GetDirectoryName(file), @"bin\Debug\MyAssembly.exe")
+            AssertEqual expectedTargetPath targetPath
+            let targetDir = project.GetBuildMacroValue("TargetDir")
+            let expectedTargetDir = Path.Combine(Path.GetDirectoryName(file), @"bin\Debug\")
+            AssertEqual expectedTargetDir targetDir
+        )
+     
+    [<Test>]
+    member public this.CreateFSharpManifestResourceName () =
+        DoWithTempFile "Test.fsproj" (fun file ->
+            let text = TheTests.FsprojTextWithProjectReferences(["foo.fs";"Bar.resx"; "Bar.de.resx"; "Xyz\Baz.ru.resx"; "Abc.resources"],[],[],"")
+            File.AppendAllText(file, text)
+            let result = Salsa.Salsa.CreateFSharpManifestResourceName file "" "" |> List.sort
+            let expected =
+                ["Abc.resources", "Abc.resources";
+                 "Bar.de.resx", "Bar.de"; 
+                 "Bar.resx", "Bar"; 
+                 "Xyz\Baz.ru.resx", "Xyz.Baz.ru"] |> List.sort
+            if expected <> result then
+                Assert.Fail ((sprintf "%A" expected) + "<>" + (sprintf "%A" result))            
+            ()
+        )
+
+    member this.GetCurrentConfigCanonicalName(project : ProjectNode) =
+        let buildMgr = project.Site.GetService(typeof<SVsSolutionBuildManager>) :?> IVsSolutionBuildManager
+        let cfgs = Array.create 1 (null : IVsProjectCfg)
+        let hr = buildMgr.FindActiveProjectCfg(System.IntPtr.Zero, System.IntPtr.Zero, project, cfgs)
+        Assert.AreEqual(VSConstants.S_OK, hr)
+        Assert.IsNotNull(cfgs.[0])
+        let mutable cfgName = ""
+        let hr = cfgs.[0].get_CanonicalName(&cfgName)
+        Assert.AreEqual(VSConstants.S_OK, hr)
+        cfgName
+
+    [<Test>]
+    member this.``MSBuildExtensibility.BrokenCompileDependsOn.WithRecovery`` () =
+        this.MakeProjectAndDoWithProjectFileAndConfigChangeNotifier(["foo.fs";"bar.fs"], [], 
+// define a legal 'Foo' configuration
+@"<PropertyGroup Condition="" '$(Configuration)|$(Platform)' == 'Foo|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>", fun project configChangeNotifier projFile -> 
+            let projFileText = File.ReadAllText(projFile)
+            // We need to add text _after_ the import of Microsoft.FSharp.targets.  
+            let i = projFileText.IndexOf("<Import Project=")
+            let i = projFileText.IndexOf(">", i)
+            let newProjFileText = projFileText.Insert(i+1, @"
+                  <PropertyGroup>
+                    <CompileDependsOn>MyTarget;$(CompileDependsOn)</CompileDependsOn>
+                  </PropertyGroup>
+                  <Target Name=""MyTarget"">
+                    <Error Condition="" '$(Configuration)'!='Foo' "" Text=""This is my error message."" ContinueOnError=""false"" />
+                  </Target>")
+            File.WriteAllText(projFile, newProjFileText)
+            project.Reload()
+            // Ensure we are not in 'Foo' config, and thus expect failure
+            let curCfgCanonicalName = this.GetCurrentConfigCanonicalName(project)
+            Assert.IsFalse(curCfgCanonicalName.StartsWith("Foo"), sprintf "default config should not be 'Foo'! in fact it had canonical name '%s'" curCfgCanonicalName)
+            // Now the project system is in a state where ComputeSourcesAndFlags will fail.
+            // Our goal is to at least be able to open individual source files and treat them like 'files outside a project' with regards to intellisense, etc.
+            // Also, if the user does 'Build', he will get an error which will help diagnose the problem.
+            let ipps = project :> Microsoft.VisualStudio.FSharp.LanguageService.IProvideProjectSite
+            let ips = ipps.GetProjectSite()
+            let expected = [| |] // Ideal behavior is [|"foo.fs";"bar.fs"|], and we could choose to improve this in the future.  For now we are just happy to now throw/crash.
+            let actual = ips.SourceFilesOnDisk()
+            Assert.AreEqual(expected, actual, "project site did not report expected set of source files")
+            // Now let's "fix the error"
+            configChangeNotifier(project, "Foo|AnyCPU")  // switch to Foo mode - <Error> should go away, project should start behaving as normal
+            let expected = [| "foo.fs"; "bar.fs" |] |> Array.map (fun filename -> Path.Combine(project.ProjectFolder, filename))
+            let actual = ips.SourceFilesOnDisk()
+#if FX_ATLEAST_45
+            let actual = if actual.Length > 0 then actual |> Seq.skip 1 |> Seq.toArray else actual // On Dev10, first file will be AssemblyAttributes.fs
+#endif
+            Assert.AreEqual(expected, actual, "project site did not report expected set of source files after recovery")
+        )
+
+    [<Test>]
+    member public this.TestBuildActions () =
+        DoWithTempFile "Test.fsproj" (fun file ->
+            let text = TheTests.FsprojTextWithProjectReferences(["foo.fs";"Bar.resx"; "Bar.de.resx"; "Xyz\Baz.ru.resx"; "Abc.resources"],[],[],"<Import Project=\"My.targets\" />")
+            // Use toolsversion 2.0 project to have predictable default set of BuildActions
+            let text = text.Replace("ToolsVersion='4.0'", "ToolsVersion='2.0'") 
+            
+            File.AppendAllText(file, text)
+            let dirName = Path.GetDirectoryName(file)
+            let targetsFile = Path.Combine(dirName, "My.targets")
+            let targetsText = @"<?xml version=""1.0"" encoding=""utf-8""?>
+                <Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
+                    <ItemGroup>
+                        <AvailableItemName Include=""MyBuildAction"" />
+                        <AvailableItemName Include=""MyBuildAction3"" />
+                    </ItemGroup>
+                </Project>"
+            File.AppendAllText(targetsFile, targetsText)
+            let sp, cnn = VsMocks.MakeMockServiceProviderAndConfigChangeNotifier()
+            let project = TheTests.CreateProject(file, "false", cnn, sp)            
+            use project = project
+            let values = project.BuildActionConverter.GetStandardValues()
+            let list = values |> Seq.cast |> Seq.map (fun (ba : BuildAction)-> ba.Name) |> Seq.toList
+            let expected = ["Compile"; "Content"; "EmbeddedResource"; "None"; "MyBuildAction"; "MyBuildAction3"]
+            if expected |> List.forall (fun i -> List.exists ((=)i) list) |> not then                
+                let s0 = sprintf "%A" expected
+                let s1 = sprintf "%A" list
+                Assert.Fail(s0 + "<>" + s1)
+            ()
+        )
+
+    [<Test>]
+    member this.``WildcardsInProjectFile.ThrowingCase`` () =
+        DoWithTempFile "Test.fsproj"(fun file ->
+            let text = TheTests.FsprojTextWithProjectReferences(["*.fs"],[],[],"")
+            File.AppendAllText(file, text)
+            let dirName= Path.GetDirectoryName(file)
+            File.AppendAllText(Path.Combine(dirName, "Foo.fs"), "do ()")
+            File.AppendAllText(Path.Combine(dirName, "Bar.fs"), "do ()")
+            let mutable exceptionThrown = false
+            try
+                let sp, cnn = VsMocks.MakeMockServiceProviderAndConfigChangeNotifier()
+                let project = TheTests.CreateProject(file, "false", cnn, sp) in project.Close() |> ignore
+            with :? CannotOpenProjectsWithWildcardsException as e ->
+                    exceptionThrown <- true
+                    AssertEqual "*.fs" e.ItemSpecification
+                    AssertEqual "Compile" e.ItemType
+            Assert.IsTrue(exceptionThrown)
+        )
+        
+    [<Test>]
+    member this.``WildcardsInProjectFile.OkCase`` () =
+        DoWithTempFile "Test.fsproj"(fun file ->
+            let text = TheTests.FsprojTextWithProjectReferences(["*.fs"],[],[],"")
+            File.AppendAllText(file, text)
+            let dirName= Path.GetDirectoryName(file)
+            let fileName = Path.Combine(dirName, "Foo.fs")
+            File.AppendAllText(fileName, "do ()")
+            let sp, cnn = VsMocks.MakeMockServiceProviderAndConfigChangeNotifier()
+            let project = TheTests.CreateProject(file, "false", cnn, sp) 
+            try
+                project.ComputeSourcesAndFlags()
+                let items = project.GetCompileItems() |> Array.toList
+                match items with
+#if FX_ATLEAST_45
+                | [ _; fn ] -> // first file is AssemblyAttributes.fs
+#else
+                | [ fn ] ->
+#endif
+                    AssertEqual fileName fn
+                | _ ->
+                    sprintf "wring set of compile items %A" items |> Assert.Fail
+                ()
+            finally
+                project.Close() |> ignore
+        )
+
+
+
+
+
+
+
+
+
+
+
+
+module Regression5312 = 
+    // Regression testing ICONS in project system dll
+    open System
+    open System.Drawing
+    open System.Runtime.InteropServices
+    [<DllImport("shell32.dll", CharSet=CharSet.Auto)>]
+    extern int32 ExtractIconEx(string szFileName, int nIconIndex,IntPtr[] phiconLarge, IntPtr[] phiconSmall,uint32 nIcons)
+
+    [<DllImport("user32.dll", EntryPoint="DestroyIcon", SetLastError=true)>]
+    extern int DestroyIcon(IntPtr hIcon)
+
+    let extractIcon (path:string) (large:bool) =
+        let n = 10 
+        let hIconLarge = Array.create n IntPtr.Zero
+        let hIconSmall = Array.create n IntPtr.Zero
+        try
+            let readIconCount = ExtractIconEx(path,0,hIconLarge,hIconSmall,uint32 n)
+            if readIconCount > 0 then
+                if large then
+                    Array.init readIconCount (fun i -> Icon.FromHandle(hIconLarge.[0]).Clone() :?> Icon)
+                else
+                    Array.init readIconCount (fun i -> Icon.FromHandle(hIconSmall.[0]).Clone() :?> Icon)
+            else
+                [| |]           
+        finally
+            hIconLarge |> Array.iter (fun ptr -> if ptr <> IntPtr.Zero then DestroyIcon ptr |> ignore<int>)
+            hIconSmall |> Array.iter (fun ptr -> if ptr <> IntPtr.Zero then DestroyIcon ptr |> ignore<int>)
+
+    /// Given path to FSharp.Project.FSharpProject.dll, check the icons are present.
+    /// Throws of failure.
+    let checkIcons nExpected (path:string) =
+        let icons = extractIcon path true
+        if icons.Length<>nExpected then failwithf "Expected %d icons in %s" nExpected path // "
+
+[<TestFixture>]
+type Utilities() = 
+    (*
+        Simulation of the code found in Xaml editor that we were crashing. The relevent code is pasted below.
+        Note that they're assuming PKT is eight bytes. This need not be true and we don't enforce it from our
+        side. We're just going to make sure to send an even number of characters (two per-byte).
+        
+        private static AssemblyName EnsureAssemblyName(Reference r) {
+            if (r.Type != prjReferenceType.prjReferenceTypeAssembly)
+                return null;
+
+            // If possible, we use the data stored in the reference
+            // to get to the assembly name.  It is much faster than
+            // cracking the manifest.
+
+            AssemblyName an = new AssemblyName();
+            // Reference.Name does not have to be the actual assembly name here (seen in Project ref cases)
+            // Identity (for Reference.Type == prjReferenceType.prjReferenceTypeAssembly) is the assembly name 
+            // without path or extension and is reserved so it can't be set in the project file by users
+            an.Name = r.Identity; 
+            an.CultureInfo = new CultureInfo(r.Culture);
+            an.Version = new Version(
+                r.MajorVersion,
+                r.MinorVersion,
+                r.BuildNumber,
+                r.RevisionNumber);
+
+            string publicTokenString = r.PublicKeyToken;
+            if (publicTokenString != null && publicTokenString.Length > 0) {
+                byte[] publicToken = new byte[8];
+                for (int i = 0; i < publicToken.Length; i++) {
+                    string byteString = publicTokenString.Substring(i * 2, 2);
+                    publicToken[i] = byte.Parse(byteString, NumberStyles.HexNumber, CultureInfo.InvariantCulture);
+                }
+                an.SetPublicKeyToken(publicToken);
+            }
+            else {
+                an.SetPublicKeyToken(new byte[0]);
+            }
+
+            try {
+                Uri uri = new Uri(r.Path);
+                an.CodeBase = uri.AbsoluteUri;
+            }
+            catch (UriFormatException) {
+                // Reference path is ill-formed or empty => no code base
+            }
+
+            return an;
+        }
+        
+        
+        
+    *)
+    
+    let SimulateXamlEditorReceivingThroughDTE(publicToken:string) = 
+        printfn "Simulating xaml pkt parsing for %s" publicToken
+        // ----------------------------------------------------------------------------------------------------
+        // Don't change code between these lines. Its simulating external code.
+        // ----------------------------------------------------------------------------------------------------
+        let ParseOneByte(i:int) = 
+            let byteString = publicToken.Substring(i * 2, 2)
+            System.Byte.Parse(byteString, NumberStyles.HexNumber, CultureInfo.InvariantCulture) |> ignore
+        [0..7] |> List.iter ParseOneByte
+        // ----------------------------------------------------------------------------------------------------
+
+    let CheckPublicKeyToString(bytes,expect) =
+        let actual = KeyToken.ToHexString(bytes)
+        Assert.AreEqual(expect, actual)
+        SimulateXamlEditorReceivingThroughDTE(actual)
+
+    [<Test>]
+    member public this.``PublicKeyToken.0000000000000000``() = CheckPublicKeyToString([|0uy;0uy;0uy;0uy;0uy;0uy;0uy;0uy|], "0000000000000000")
+        
+    [<Test>]
+    member public this.``PublicKeyToken.0000000000000001``() = CheckPublicKeyToString([|0uy;0uy;0uy;0uy;0uy;0uy;0uy;1uy|], "0000000000000001")
+
+    [<Test>]
+    member public this.``PublicKeyToken.0a00000000000001``() = CheckPublicKeyToString([|0xauy;0uy;0uy;0uy;0uy;0uy;0uy;1uy|], "0a00000000000001")
+
+    [<Test>]      
+    member public this.``CheckIconsInProjectSystemDLL_Regression5312``() = 
+        let path = typeof<Microsoft.VisualStudio.FSharp.ProjectSystem.FSharpProjectPackage>.Assembly.Location
+        Regression5312.checkIcons 4 path
+        ()
+
+
+
+#if DEBUGGERVISUALIZER
+module internal DebugViz =
+    open System.Windows.Forms
+    open System.Drawing
+    open Microsoft.VisualStudio.DebuggerVisualizers
+    open System.Runtime.Serialization.Formatters.Binary
+    open System.Runtime.Serialization
+    open System.Collections.ObjectModel
+
+    // debugger visualizer for HierarchyNodes
+    [<Serializable>]
+    type MyTreeNode(_data : string, _children : Collection<MyTreeNode>) = 
+        let mutable data = _data
+        let mutable children = _children
+        new() = MyTreeNode("", new Collection<MyTreeNode>())
+        new(data) = MyTreeNode(data, new Collection<MyTreeNode>())
+        new(data, child : MyTreeNode, ()) = let nodes = new Collection<MyTreeNode>()
+                                            nodes.Add(child)
+                                            MyTreeNode(data, nodes)
+        
+        member this.Data with get() = data
+                         and set(s) = data <- s
+        member this.Nodes with get() = children
+                          and set(c) = children <- c
+        member this.ToTreeNode() =
+            let (result : TreeNode) = this.ToTreeNode(false) 
+            result.Toggle()
+            result
+        member this.ToTreeNode(toggle) =
+            let result = new TreeNode(data)
+            for mtn in children do
+                result.Nodes.Add(mtn.ToTreeNode(true)) |> ignore
+            if toggle then
+                result.Toggle()
+            result
+
+    type MyVisualizerObjectSource() =
+        inherit VisualizerObjectSource()
+        override this.CreateReplacementObject(target, incomingData) =
+            null : Object
+        override this.GetData(target, outgoingData) =
+            let node = MyVisualizerObjectSource.MakeFromObject(target)
+            let formatter = new BinaryFormatter()
+            formatter.Serialize(outgoingData, node)
+            ()
+        override this.TransferData(target, incomingData, outgoingData) =
+            this.GetData(target, outgoingData)
+        static member MakeFromObject(o : Object) =
+            let hn = o :?> HierarchyNode
+            if hn <> null then
+                let rec Make(n : HierarchyNode) =
+                    let result = new MyTreeNode(n.Caption)
+                    let mutable c = n.FirstChild
+                    while c <> null do
+                        result.Nodes.Add(Make(c))
+                        c <- c.NextSibling
+                    result
+                Make(hn)
+            else failwith "expected a HierarchyNode"
+        
+    type MyForm(myNode : MyTreeNode) as this =
+        inherit Form()
+
+        static let normalFont = new Font("Courier New", 12.0f, FontStyle.Regular);
+        static let boldFont = new Font("Courier New", 12.0f, FontStyle.Bold);
+
+        let node = myNode.ToTreeNode()
+        // REVIEW work on auto-sizing the window
+        let maxX = 820;
+        let maxY = 620;
+        let tv = new TreeView()
+        do
+            tv.Font <- boldFont
+            tv.Nodes.Add(node) |> ignore
+            tv.Location <- new System.Drawing.Point(0, 0)
+            tv.Size <- new System.Drawing.Size(maxX, maxY)
+            tv.DrawMode <- TreeViewDrawMode.OwnerDrawText
+            tv.DrawNode.AddHandler(new DrawTreeNodeEventHandler(this.DrawNode))
+            this.Controls.Add(tv)
+            this.Size <- new System.Drawing.Size(maxX + 15, maxY + 30)
+            this.Location <- new System.Drawing.Point(10, 10)
+
+        member this.DrawNode sender (e : DrawTreeNodeEventArgs) =
+            let text = e.Node.Text;
+            let g = e.Graphics
+            let size1 = g.MeasureString(text, boldFont)
+            let rec1 = RectangleF.FromLTRB(single e.Bounds.Left, single e.Bounds.Top, single e.Bounds.Left + size1.Width+1.0f, single e.Bounds.Top + size1.Height+1.0f)
+            e.Graphics.DrawString(text, boldFont, Brushes.Black, rec1)
+            ()
+
+    type MyExpandedDialogDebuggerVisualizer() =
+        inherit DialogDebuggerVisualizer()
+        override this.Show(windowService, objectProvider) =
+            let formatter = new BinaryFormatter()
+            let input = objectProvider.GetData()
+            let node = formatter.Deserialize(input, null) :?> MyTreeNode
+            let form = new MyForm(node)
+            windowService.ShowDialog(form :> Form) |> ignore
+        static member TestShowVisualizer(objectToVisualize : HierarchyNode) =
+            let serializable = MyVisualizerObjectSource.MakeFromObject(box objectToVisualize)
+            let visualizerHost = new VisualizerDevelopmentHost(serializable, typeof<MyExpandedDialogDebuggerVisualizer>)
+            visualizerHost.ShowVisualizer()
+
+    [<assembly: DebuggerVisualizer(typeof<MyExpandedDialogDebuggerVisualizer>, 
+                                   typeof<MyVisualizerObjectSource>,
+                                   Target = typeof<HierarchyNode>,
+                                   Description = "HierarchyNode visualizer")>]
+    [<assembly: DebuggerVisualizer(typeof<MyExpandedDialogDebuggerVisualizer>, 
+                                   typeof<MyVisualizerObjectSource>,
+                                   Target = typeof<FSharpProjectNode>,
+                                   Description = "HierarchyNode visualizer")>]
+    [<assembly: DebuggerVisualizer(typeof<MyExpandedDialogDebuggerVisualizer>, 
+                                   typeof<MyVisualizerObjectSource>,
+                                   Target = typeof<FSharpFileNode>,
+                                   Description = "HierarchyNode visualizer")>]
+    [<assembly: DebuggerVisualizer(typeof<MyExpandedDialogDebuggerVisualizer>, 
+                                   typeof<MyVisualizerObjectSource>,
+                                   Target = typeof<UnitTestingFSharpProjectNode>,
+                                   Description = "HierarchyNode visualizer")>]
+    do
+        () // module-level do for assembly-level attribute                     
+#endif
\ No newline at end of file
diff --git a/vsintegration/src/unittests/Tests.ProjectSystem.MultiTargeting.fs b/vsintegration/src/unittests/Tests.ProjectSystem.MultiTargeting.fs
new file mode 100644
index 0000000..f22e0c1
--- /dev/null
+++ b/vsintegration/src/unittests/Tests.ProjectSystem.MultiTargeting.fs
@@ -0,0 +1,166 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+namespace UnitTests.Tests.ProjectSystem
+
+open System
+open System.Collections.Generic
+open System.IO
+open System.Reflection
+open System.Text.RegularExpressions
+open System.Xml.Linq
+open NUnit.Framework
+open Salsa
+open UnitTests.TestLib.Utils.Asserts
+open UnitTests.TestLib.Utils.FilesystemHelpers
+open UnitTests.TestLib.ProjectSystem
+open Microsoft.VisualStudio.FSharp.ProjectSystem
+
+
+[<TestFixture>]
+type MultiTargeting() = 
+    inherit TheTests()
+    
+    // Multitargeting tests.
+    // For these test cases, we basically test adding a reference and checking the icon state.
+    // It's worth pointing out that while we need a valid assembly, the version of the assembly
+    // is returned by the VsTargetFrameworkAssemblies service. Therefore, to test, we provide
+    // a mock that returns the requested version, and ignore the real version of the assembly.
+
+    member private this.prepTest(projFile) =
+        let dirName = Path.GetDirectoryName(projFile)
+        let libDirName = Directory.CreateDirectory(Path.Combine(dirName, "lib")).FullName
+        let codeBase = (new Uri(Assembly.GetExecutingAssembly().CodeBase)).LocalPath |> Path.GetDirectoryName
+        let refLibPath = Path.Combine(libDirName, "FSharp.Core.Unittests.dll")
+        File.Copy(Path.Combine(codeBase, "FSharp.Core.Unittests.dll"), refLibPath)
+        File.AppendAllText(projFile, TheTests.FsprojTextWithProjectReferencesAndOtherFlags([], [refLibPath], [], null, "", "v2.0"))
+        refLibPath
+
+    [<Test>]
+    member public this.``Multitargeting.CheckIconForMismatchedAssemblyReference`` () =
+        DoWithTempFile "Test.fsproj" (fun projFile ->
+            let sp, ccn = VsMocks.MakeMockServiceProviderAndConfigChangeNotifier40()
+            let refLibPath = this.prepTest(projFile)
+            use project = TheTests.CreateProject(projFile, "true", ccn, sp)
+            let l = new List<AssemblyReferenceNode>()
+            project.FindNodesOfType(l)
+            Assert.AreEqual(1, l.Count)
+            Assert.AreEqual(refLibPath, l.[0].Url)
+            Assert.AreEqual(refLibPath, l.[0].Caption)
+            let ref = l.[0]
+            Assert.AreEqual(true, ref.CanShowDefaultIcon())
+        )
+
+    [<Test>]
+    member public this.``Multitargeting.CheckIconForMatchedAssemblyReference20`` () =
+        DoWithTempFile "Test.fsproj" (fun projFile ->
+            let sp, ccn = VsMocks.MakeMockServiceProviderAndConfigChangeNotifier20()
+            let refLibPath = this.prepTest(projFile)
+            use project = TheTests.CreateProject(projFile, "true", ccn, sp)
+            let l = new List<AssemblyReferenceNode>()
+            project.FindNodesOfType(l)
+            Assert.AreEqual(1, l.Count)
+            Assert.AreEqual(refLibPath, l.[0].Url)
+            Assert.AreEqual(refLibPath, l.[0].Caption)
+            let ref = l.[0]
+            Assert.AreEqual(true, ref.CanShowDefaultIcon())
+        )
+        
+    [<Test>]
+    member public this.``Multitargeting.DetermineRuntimeAndSKU`` () =
+        DoWithTempFile "Test.fsproj" (fun projFile ->
+            let sp, ccn = VsMocks.MakeMockServiceProviderAndConfigChangeNotifier40()
+            let refLibPath = this.prepTest(projFile)
+            use project = TheTests.CreateProject(projFile, "true", ccn, sp)
+            
+            let validate (fn : System.Runtime.Versioning.FrameworkName) eR eS =
+                let (name, runtime, sku) = project.DetermineRuntimeAndSKU(fn.ToString())
+                Assert.AreEqual(eR, runtime)
+                Assert.AreEqual(eS, sku)
+            validate (new System.Runtime.Versioning.FrameworkName(".NETFramework", new System.Version(4, 0))) "v4.0" ".NETFramework,Version=v4.0"
+            validate (new System.Runtime.Versioning.FrameworkName(".NETFramework", new System.Version(2, 0))) "v2.0.50727" null
+        )
+        
+    [<Test>]
+    member public this.``Multitargeting.AppConfigNoStartupNode`` () =
+        let root = XElement.Parse("<Configuration></Configuration>")
+        let dirty = LangConfigFile.PatchUpXml(root, "version", "sku")
+        Assert.IsTrue(dirty)
+        Assert.IsTrue(root.ToString().Contains("<supportedRuntime version=\"version\" sku=\"sku\" />"))
+
+    [<Test>]
+    member public this.``Multitargeting.AppConfigVersionExistsAddNewSku`` () =
+        let root = XElement.Parse("<Configuration><startup><supportedRuntime version=\"version\" /></startup></Configuration>")
+        let dirty = LangConfigFile.PatchUpXml(root, "version", "sku")
+        Assert.IsTrue(dirty)
+        Assert.IsTrue(root.ToString().Contains("<supportedRuntime version=\"version\" sku=\"sku\" />"))
+
+    [<Test>]
+    member public this.``Multitargeting.AppConfigVersionExistsReplaceSku`` () =
+        let root = XElement.Parse("<Configuration><startup><supportedRuntime version=\"version\" sku=\"oldsku\" /></startup></Configuration>")
+        let dirty = LangConfigFile.PatchUpXml(root, "version", "sku")
+        Assert.IsTrue(dirty)
+        Assert.IsTrue(root.ToString().Contains("<supportedRuntime version=\"version\" sku=\"sku\" />"))
+
+    [<Test>]
+    member public this.``Multitargeting.AppConfigVersionExistsRemoveSku`` () =
+        let root = XElement.Parse("<Configuration><startup><supportedRuntime version=\"version\" sku=\"oldsku\" /></startup></Configuration>")
+        let dirty = LangConfigFile.PatchUpXml(root, "version", null) 
+        Assert.IsTrue(dirty)
+        Assert.IsTrue(root.ToString().Contains("<supportedRuntime version=\"version\" />"))
+
+    [<Test>]
+    member public this.``Multitargeting.AppConfigVersionReplaceOldRuntime`` () =
+        let root = XElement.Parse("<Configuration><startup><supportedRuntime version=\"versionold\" sku=\"oldsku\" /></startup></Configuration>")
+        let dirty = LangConfigFile.PatchUpXml(root, "version", "sku")
+        Assert.IsTrue(dirty)
+        Assert.IsTrue(root.ToString().Contains("<supportedRuntime version=\"version\" sku=\"sku\" />"))
+        Assert.IsFalse(root.ToString().Contains("<supportedRuntime version=\"versionold\" sku=\"oldsku\" />"))
+
+    [<Test>]
+    member public this.``Multitargeting.AppConfigVersionReplaceOldRuntimes`` () =
+        let root = XElement.Parse("<Configuration><startup><supportedRuntime version=\"versionold\" sku=\"oldsku\" /><supportedRuntime version=\"versionold2\" /></startup></Configuration>")
+        let dirty = LangConfigFile.PatchUpXml(root, "version", "sku")
+        Assert.IsTrue(dirty)
+        Assert.IsTrue(root.ToString().Contains("<supportedRuntime version=\"version\" sku=\"sku\" />"))
+        Assert.IsFalse(root.ToString().Contains("<supportedRuntime version=\"versionold\" sku=\"oldsku\" />"))
+        Assert.IsFalse(root.ToString().Contains("<supportedRuntime version=\"versionold2\" />"))
+
+    [<Test>]
+    member public this.``Multitargeting.TestFrameworkNameToVersionString`` () =
+        let validatePair name str =
+            let res = HierarchyNode.GetFrameworkVersionString(name)
+            Assert.AreEqual(str, res)
+
+        validatePair (new System.Runtime.Versioning.FrameworkName(".NETFramework", new System.Version(4,0))) "v4.0"
+        validatePair (new System.Runtime.Versioning.FrameworkName(".NETFramework", new System.Version(4,0,5))) "v4.0.5"
+        validatePair (new System.Runtime.Versioning.FrameworkName(".NETFramework", new System.Version(4,0,256))) "v4.0"
+        validatePair (new System.Runtime.Versioning.FrameworkName(".NETFramework", new System.Version(4,0,50727))) "v4.0"
+        validatePair (new System.Runtime.Versioning.FrameworkName(".NETFramework", new System.Version(2,0,50727,0))) "v2.0"
+        validatePair (new System.Runtime.Versioning.FrameworkName(".NETFramework", new System.Version(2,0,50727,5))) "v2.0"
+        validatePair (new System.Runtime.Versioning.FrameworkName(".NETFramework", new System.Version(2,0,5,5))) "v2.0.5"
+        validatePair (new System.Runtime.Versioning.FrameworkName(".NETFramework", new System.Version(2,0,0))) "v2.0"
+        validatePair (new System.Runtime.Versioning.FrameworkName(".NETFramework", new System.Version(2,0,0,0))) "v2.0"
+        validatePair (new System.Runtime.Versioning.FrameworkName(".NETFramework", new System.Version(2,0,0,1))) "v2.0"
+
+        (*
+    [<Test>]
+    member public this.``Multitargeting.AddAppConfigIfRetargetTo40Full`` () =
+        DoWithTempFile "Test.fsproj" (fun projFile ->
+            let sp, ccn = VsMocks.MakeMockServiceProviderAndConfigChangeNotifier20()
+            
+            // add mock service for SLocalRegistry so that CreateInstance on it will return a text buffer
+            sp.AddService (typeof<SLocalRegistry>, box(VsMocks.vsLocalRegistry (fun () -> VsMocks.Vs.MakeTextLines())), false)
+            
+            let refLibPath = this.prepTest(projFile)
+            use project = TheTests.CreateProject(projFile, "true", ccn, sp)
+            let fn = new System.Runtime.Versioning.FrameworkName(".NETFramework", new System.Version(4, 0))
+            project.FixupAppConfigOnTargetFXChange(fn.ToString()) |> ignore
+            let appFile = Path.Combine((Path.GetDirectoryName projFile), "app.config")
+            let appText = System.IO.File.ReadAllText(appFile)
+            Assert.IsTrue(appText.Contains("<supportedRuntime version=\"v4.0\" sku=\".NETFramework,Version=v4.0\" />"))
+            //Assert.IsTrue(appText.Contains("<supportedRuntime version=\"v4.0\" sku=\".NETFramework,Version=v4.0,Profile=Client\" />"))
+            //Assert.IsTrue(appText.Contains("<supportedRuntime version=\"v2.0.50727\" sku=\"Client\" />"))
+            //Assert.IsTrue(appText.Contains("<supportedRuntime version=\"v2.0.50727\" />"))
+            ()
+        )
+        *)
diff --git a/vsintegration/src/unittests/Tests.ProjectSystem.Project.fs b/vsintegration/src/unittests/Tests.ProjectSystem.Project.fs
new file mode 100644
index 0000000..31bc9df
--- /dev/null
+++ b/vsintegration/src/unittests/Tests.ProjectSystem.Project.fs
@@ -0,0 +1,817 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+namespace UnitTests.Tests.ProjectSystem
+
+// System namespaces
+open System
+open System.Collections.Generic
+open System.IO
+open System.Text.RegularExpressions
+open System.Xml.Linq
+open NUnit.Framework
+
+// VS namespaces 
+open Microsoft.VisualStudio.Shell.Interop
+open Microsoft.VisualStudio.FSharp.ProjectSystem
+
+// Internal unittest namespaces
+open Salsa
+open UnitTests.TestLib.Utils.Asserts
+open UnitTests.TestLib.Utils.FilesystemHelpers
+open UnitTests.TestLib.ProjectSystem
+
+
+[<TestFixture>]
+type Project() = 
+    inherit TheTests()
+
+
+    //TODO: look for a way to remove the helper functions
+    static let ANYTREE = Tree("",Nil,Nil)
+    /////////////////////////////////
+    // project helpers
+    static let SaveProject(project : UnitTestingFSharpProjectNode) =
+        project.Save(null, 1, 0u) |> ignore
+
+    static let DefaultBuildActionOfFilename(filename) : Salsa.BuildAction = 
+        match Path.GetExtension(filename) with 
+        | ".fsx" -> Salsa.BuildAction.None
+        | ".resx"
+        | ".resources" -> Salsa.BuildAction.EmbeddedResource
+        | _ -> Salsa.BuildAction.Compile            
+
+    static let GetReferenceContainerNode(project : ProjectNode) =
+        let l = new List<ReferenceContainerNode>()
+        project.FindNodesOfType(l)
+        l.[0]     
+
+    [<Test>]    
+    member public this.NoNewFolderOnProjectMenu() =
+        printfn "starting..."
+        let package = new FSharpProjectPackage()
+        let project = new FSharpProjectNode(package)
+        let guidCmdGroup = VsMenus.guidStandardCommandSet97
+        let cmdEnum = Microsoft.VisualStudio.VSConstants.VSStd97CmdID.NewFolder
+        let mutable result = new QueryStatusResult()
+        let (pCmdText : IntPtr) = 0n
+        printfn "call qson..."
+        let x = project.QueryStatusOnNode(guidCmdGroup, uint32(cmdEnum), pCmdText, &result)
+        printfn "and..."
+        AssertEqual x VSConstants.S_OK
+        if (result &&& QueryStatusResult.INVISIBLE) = enum 0 then
+            Assert.Fail("Unexpected: New Folder was not invisible")
+        ()    
+
+    [<Test>]
+    member public this.``FsprojFileToSolutionExplorer.FileOrderInFsprojIsRespected.Case1``() =
+        let compileItems = ["one.fs"; "two.fs"; "three.fs"]
+        let expect = Tree("References", ANYTREE,
+                     Tree("one.fs", Nil,
+                     Tree("two.fs", Nil,
+                     Tree("three.fs", Nil, Nil))))
+        // We expect nodes in the solution explorer to appear in the same order as
+        // the msbuild file - e.g. "one" "two" "three" rather than alphabetized
+        // "one" "three" "two"
+        this.``FsprojFileToSolutionExplorer.PositiveTest``(compileItems, "", expect)
+
+    [<Test>]
+    member public this.``FsprojFileToSolutionExplorer.FileOrderInFsprojIsRespected.Case2``() =
+        let compileItems = [@"A\B\D\foo.fs"; @"A\B\C\bar.fs"]
+        let expect = Tree("References", ANYTREE,
+                     Tree("A", 
+                         Tree("B",
+                             Tree("D", 
+                                 Tree("foo.fs", Nil, Nil),
+                             Tree("C", 
+                                 Tree("bar.fs", Nil, Nil),
+                                 Nil)), Nil), Nil))
+        // no alphabetization of files or folders
+        this.``FsprojFileToSolutionExplorer.PositiveTest``(compileItems, "", expect)
+
+    [<Test>]
+    member public this.``FsprojFileToSolutionExplorer.FileOrderInFsprojIsRespected.Case3``() =
+        let compileItems = [@"B\foo.fs"; @"A\bar.fs"]
+        let other = @"
+          <ItemGroup>
+            <Folder Include='A' />
+          </ItemGroup>
+          "
+        let expect = Tree("References", ANYTREE,
+                     Tree("B",
+                         Tree("foo.fs", Nil, Nil),
+                     Tree("A", 
+                         Tree("bar.fs", Nil, Nil),
+                         Nil)))
+        // Including folder should not put folder at front of other folders
+        this.``FsprojFileToSolutionExplorer.PositiveTest``(compileItems, other, expect)
+
+    [<Test>]
+    member public this.``FsprojFileToSolutionExplorer.FileOrderInFsprojIsRespected.Case4``() =
+        let compileItems = [@"foo.fs"; @"A\bar.fs"]
+        let other = @"
+          <ItemGroup>
+            <Folder Include='A' />
+          </ItemGroup>
+          "
+        let expect = Tree("References", ANYTREE,
+                     Tree("foo.fs", Nil,
+                     Tree("A", 
+                         Tree("bar.fs", Nil, Nil),
+                         Nil)))
+        // Including folder should not put folder at front of files
+        this.``FsprojFileToSolutionExplorer.PositiveTest``(compileItems, other, expect)
+
+
+    [<Test>]
+    member public this.``FsprojFileToSolutionExplorer.LinksIntoFoldersAreRespected``() =
+        let compileItems = []
+        let other = @"
+          <ItemGroup>
+            <Compile Include='foo.fs' />
+            <Compile Include='..\bar.fs' >
+                <Link>A\bar.fs</Link>
+            </Compile>
+            <Compile Include='A\qux.fs' />
+          </ItemGroup>
+          "
+        let expect = Tree("References", ANYTREE,
+                     Tree("foo.fs", Nil,
+                     Tree("A", 
+                         Tree("bar.fs", Nil,
+                         Tree("qux.fs", Nil, Nil)),
+                         Nil)))
+        this.``FsprojFileToSolutionExplorer.PositiveTest``(compileItems, other, expect)
+
+
+    [<Test>]
+    member public this.``Links.AddLinkToRootWorks``() =
+        let compileItems = [@"Folder\foo.fs"; @"bar.fs"; ]
+        this.MakeProjectAndDoWithProjectFile(compileItems, [], "", (fun project fileName ->
+            this.EnsureCausesNotification(project, fun() ->
+                let f = Internal.Utilities.FileSystem.Path.SafeGetFullPath(Path.Combine(project.ProjectFolder, @"..\qux.fs"))
+                project.AddLinkedItem(project, [| f |], Array.create 1 (new VSADDRESULT())) |> ValidateOK
+            )
+            let expect = Tree("References", ANYTREE,
+                         Tree("Folder", 
+                            Tree("foo.fs",Nil,Nil), 
+                         Tree("bar.fs", Nil,
+                         Tree("qux.fs", Nil,Nil))))
+            TheTests.AssertSameTree(expect, project.FirstChild)
+            SaveProject(project)
+            let fsprojFileText = File.ReadAllText(fileName)
+            printfn "%s" fsprojFileText
+            let regexStr = @"<ItemGroup>\s*<Compile Include=""Folder\\foo.fs"" />\s*<Compile Include=""bar.fs"" />\s*<Compile Include=""..\\qux.fs"">\s*<Link>qux.fs</Link>"
+            TheTests.HelpfulAssertMatches '<' regexStr fsprojFileText
+        ))
+
+    [<Test>]
+    member public this.``Links.AddLinkToSubfolderWorks``() =
+        let compileItems = [@"bar.fs"; @"Folder\foo.fs"; ]
+        this.MakeProjectAndDoWithProjectFile(compileItems, [], "", (fun project fileName ->
+            let folder = TheTests.FindNodeWithCaption(project, "Folder")
+            this.EnsureCausesNotification(project, fun() ->
+                let f = Internal.Utilities.FileSystem.Path.SafeGetFullPath(Path.Combine(project.ProjectFolder, @"..\qux.fs"))
+                project.AddLinkedItem(folder, [| f |], Array.create 1 (new VSADDRESULT())) |> ValidateOK
+            )
+            let expect = Tree("References", ANYTREE,
+                         Tree("bar.fs", Nil,
+                         Tree("Folder", 
+                            Tree("foo.fs", Nil,
+                            Tree("qux.fs", Nil,Nil)), Nil)))
+            TheTests.AssertSameTree(expect, project.FirstChild)
+            SaveProject(project)
+            let fsprojFileText = File.ReadAllText(fileName)
+            printfn "%s" fsprojFileText
+            let regexStr = @"<ItemGroup>\s*<Compile Include=""bar.fs"" />\s*<Compile Include=""Folder\\foo.fs"" />\s*<Compile Include=""..\\qux.fs"">\s*<Link>Folder\\qux.fs</Link>"
+            TheTests.HelpfulAssertMatches '<' regexStr fsprojFileText
+        ))
+
+    [<Test>]
+    member public this.``Links.AddLinkToRootWorksForNonFsFile``() =
+        let compileItems = [@"Folder\foo.fs"; @"bar.fs"; ]
+        this.MakeProjectAndDoWithProjectFile(compileItems, [], "", (fun project fileName ->
+            this.EnsureCausesNotification(project, fun() ->
+                // Note: this is not the same code path as the UI, but it is close
+                project.MoveNewlyAddedFileToBottomOfGroup (fun () ->
+                    let f = Internal.Utilities.FileSystem.Path.SafeGetFullPath(Path.Combine(project.ProjectFolder, @"..\qux.resx"))
+                    project.AddLinkedItem(project, [| f |], Array.create 1 (new VSADDRESULT())) |> ValidateOK
+                )
+            )
+            let expect = Tree("References", ANYTREE,
+                         Tree("Folder", 
+                            Tree("foo.fs",Nil,Nil), 
+                         Tree("bar.fs", Nil,
+                         Tree("qux.resx", Nil,Nil))))
+            TheTests.AssertSameTree(expect, project.FirstChild)
+            SaveProject(project)
+            let fsprojFileText = File.ReadAllText(fileName)
+            printfn "%s" fsprojFileText
+            let regexStr = @"<ItemGroup>\s*<Compile Include=""Folder\\foo.fs"" />\s*<Compile Include=""bar.fs"" />\s*<EmbeddedResource Include=""..\\qux.resx"">\s*<Link>qux.resx</Link>"
+            TheTests.HelpfulAssertMatches '<' regexStr fsprojFileText
+        ))
+    
+    [<Test>]
+    member public this.``Removal.ExcludeFileShouldDirtyProjectFileAndBeSeenOnDiskAfterSave``() =
+        let items = MSBuildItems([CompileItem "foo.fs"; CompileItem "bar.fs"])
+        this.MakeProjectAndDoWithProjectFile([], [], items.ToString(), (fun project fileName ->
+            let toVerify = @"<Compile Include=""foo.fs"""
+            // ensure is there to start
+            SaveProject(project)
+            let fsprojFileText = File.ReadAllText(fileName)
+            printfn "%s" fsprojFileText
+            AssertEqualMsg true (fsprojFileText.Contains(toVerify)) "original assumption of this test was invalid"
+            // remove it
+            let foo = TheTests.FindNodeWithCaption(project, "foo.fs")
+            foo.Remove(false) // false='removeFromStorage' - thus this is like 'Exclude from project'
+            // ensure things are right
+            AssertEqualMsg true project.IsProjectFileDirty "the project file was not dirtied"
+            SaveProject(project)
+            let fsprojFileText = File.ReadAllText(fileName)
+            printfn "%s" fsprojFileText
+            AssertEqualMsg false (fsprojFileText.Contains(toVerify)) "it was not removed from the .fsproj on disk"
+        ))
+
+    [<Test>]
+    member public this.``Removal.RemoveReferenceShouldDirtyProjectFileAndBeSeenOnDiskAfterSave``() =
+        let items = MSBuildItems([CompileItem "foo.fs"; CompileItem "bar.fs"])
+        this.MakeProjectAndDoWithProjectFile([], ["System"], items.ToString(), (fun project fileName ->
+            let toVerify = @"<Reference Include=""System"""
+            // ensure is there to start
+            SaveProject(project)
+            let fsprojFileText = File.ReadAllText(fileName)
+            printfn "%s" fsprojFileText
+            AssertEqualMsg true (fsprojFileText.Contains(toVerify))  "original assumption of this test was invalid"
+            // remove it
+            let refSystem = TheTests.FindNodeWithCaption(project, "System")
+            refSystem.Remove(false)
+            // ensure things are right
+            AssertEqualMsg true project.IsProjectFileDirty "the project file was not dirtied"
+            SaveProject(project)
+            let fsprojFileText = File.ReadAllText(fileName)
+            printfn "%s" fsprojFileText
+            AssertEqualMsg false (fsprojFileText.Contains(toVerify)) "it was not removed from the .fsproj on disk"
+        ))
+
+    [<Test>]
+    member public this.``FsprojFileToSolutionExplorer.FileMovement.MoveUpShouldDirtyProject``() =
+        let items = MSBuildItems([CompileItem "foo.fs"; CompileItem "bar.fs"])
+        this.MakeProjectAndDoWithProjectFile([], [], items.ToString(), (fun project fileName ->
+            // Save the project first, then move the file, and check for dirty.
+            SaveProject(project)
+            let foo = TheTests.FindNodeWithCaption(project, "foo.fs")
+            let bar = TheTests.FindNodeWithCaption(project, "bar.fs")
+            TheTests.MoveUp(bar)
+            AssertEqual true project.IsProjectFileDirty
+            // Tests the tree
+            let expect = Tree("References", ANYTREE,
+                         Tree("bar.fs", Nil,
+                         Tree("foo.fs", Nil, Nil)))
+            TheTests.AssertSameTree(expect, project.FirstChild)
+        ))
+
+    [<Test>]
+    member public this.``FsprojFileToSolutionExplorer.FileMovement.MoveDownShouldDirtyProject``() =
+        let items = MSBuildItems([CompileItem "foo.fs"; CompileItem "bar.fs"])
+        this.MakeProjectAndDoWithProjectFile([], [], items.ToString(), (fun project fileName ->
+            // Save the project first, then move the file, and check for dirty.
+            SaveProject(project)
+            let foo = TheTests.FindNodeWithCaption(project, "foo.fs")
+            let bar = TheTests.FindNodeWithCaption(project, "bar.fs")
+            TheTests.MoveDown(foo)
+            AssertEqual true project.IsProjectFileDirty
+            // Tests the tree
+            let expect = Tree("References", ANYTREE,
+                         Tree("bar.fs", Nil,
+                         Tree("foo.fs", Nil, Nil)))
+            TheTests.AssertSameTree(expect, project.FirstChild)
+        ))
+
+    member this.SampleEntities = [CompileItem @"foo.fs"; FolderItem @"AnEmptyFolder\"; LinkedCompileItem(@"..\blah.fs", @"link.fs"); OtherItem(@"Content", @"foo.txt"); OtherItem(@"FsLex", @"lex.mll")]
+
+    member private this.SampleFileEntity = ([CompileItem "bar.fs"], fun t -> Tree("bar.fs", Nil, t))
+    
+    member private this.SampleEmptyFolderEntity = ([FolderItem @"MyFolder\"], fun t -> Tree("MyFolder", Nil, t))
+
+    member private this.SampleFolderWithItemsEntity = ([CompileItem @"MyFolder\x1.fs"; CompileItem @"MyFolder\Sub\x2.fs"; CompileItem @"MyFolder\x3.fs"], 
+                                                       fun t -> Tree("MyFolder", 
+                                                                    Tree("x1.fs", Nil, 
+                                                                    Tree("Sub", 
+                                                                        Tree("x2.fs", Nil, Nil), 
+                                                                    Tree("x3.fs", Nil, Nil))),
+                                                                t))
+
+    [<Test>]
+    member public this.``SpecificVersion.OptionsSavedToFsprojFile``() =
+        let items = MSBuildItems( [CompileItem "foo.fs"] )
+        this.MakeProjectAndDoWithProjectFile([], ["System"], items.ToString(), (fun project fileName ->
+            let WithName name seq = Seq.filter (fun (e:XElement) -> e.Name.LocalName = name) seq
+            let WithAttrName name seq = Seq.filter (fun (e:XAttribute) -> e.Name.LocalName = name) seq
+            let system = TheTests.FindNodeWithCaption(project, "System")
+            let system = system :?> AssemblyReferenceNode
+            let a = [| false, (fun (e:XElement) -> 
+                            let expected = XDocument.Load(new StringReader(@"<Reference Include=""System""><SpecificVersion>False</SpecificVersion></Reference>")).Root
+                            TheTests.AssertSimilarXml(expected, e))
+                       true, (fun (e:XElement) -> 
+                            let expected = XDocument.Load(new StringReader(@"<Reference Include=""ANY""><SpecificVersion>True</SpecificVersion></Reference>")).Root
+                            TheTests.AssertSimilarXml(expected, e)
+                            let inc = e.Attributes() |> WithAttrName "Include" |> Seq.head
+                            Assert.IsTrue(inc.Value.StartsWith("System, Version", StringComparison.Ordinal), "assembly reference lacks version"))
+                       false, (fun (e:XElement) -> 
+                            let expected = XDocument.Load(new StringReader(@"<Reference Include=""ANY""><SpecificVersion>False</SpecificVersion></Reference>")).Root
+                            TheTests.AssertSimilarXml(expected, e)
+                            let inc = e.Attributes() |> WithAttrName "Include" |> Seq.head
+                            Assert.IsTrue(inc.Value.StartsWith("System, Version", StringComparison.Ordinal), "assembly reference lacks version")) 
+                    |]
+            let props = system.NodeProperties :?> AssemblyReferenceProperties
+            for v, f in a do
+                props.SpecificVersion <- v
+                // test that it manifests properly in .fsproj file
+                SaveProject(project)
+                let fsprojFileText = File.ReadAllText(fileName)
+                let xDoc = XDocument.Load(new StringReader(fsprojFileText))
+                let refNode = xDoc.Descendants() |> WithName "Reference" |> Seq.head 
+                printfn "%s" fsprojFileText
+                f refNode
+        ))
+    
+    [<Test>]
+    member public this.``FsprojFileToSolutionExplorer.FileRenaming.RenamingAFileDoesNotChangeOrderInSolutionExplorerOrMSBuild``() =
+        for entity, treeMaker in [this.SampleFileEntity; this.SampleEmptyFolderEntity] do
+            let items = MSBuildItems( [CompileItem "foo.fs"] @ entity )
+            this.MakeProjectAndDoWithProjectFile([], [], items.ToString(), (fun project fileName ->
+                // ensure things look right at start
+                let expect = Tree("References", ANYTREE,
+                             Tree("foo.fs", Nil,
+                             treeMaker(Nil)))
+                TheTests.AssertSameTree(expect, project.FirstChild)
+                let foo = TheTests.FindNodeWithCaption(project, "foo.fs")
+                // rename it
+                VsMocks.vsRunningDocumentTableFindAndLockDocumentVsHierarchyMock <- project
+                (foo :?> FileNode).RenameFileNode(project.ProjectFolder + "\\foo.fs", project.ProjectFolder + "\\zzz.fs", foo.Parent.ID) |> ignore
+                // test that it did not move in solution explorer
+                let expect = Tree("References", ANYTREE,
+                             Tree("zzz.fs", Nil,
+                             treeMaker(Nil)))
+                TheTests.AssertSameTree(expect, project.FirstChild) 
+                // test that it did not move in MSBuild
+                SaveProject(project)
+                let fsprojFileText = File.ReadAllText(fileName)
+                printfn "%s" fsprojFileText
+                let expectedItems = MSBuildItems( [CompileItem "zzz.fs"] @ entity )
+                let regexStr = expectedItems.AsRegexString()
+                TheTests.HelpfulAssertMatches '<' regexStr fsprojFileText
+            ))
+
+    member public this.``FsprojFileToSolutionExplorer.FileMovement.EntityCanBeMovedUpAbove``(otherEntity) =
+        let (otherEntityItems, otherTreeMaker) = otherEntity
+        for entity in this.SampleEntities do
+            printfn "=========> testing moving %s" (entity.ToString())
+            let items = MSBuildItems( otherEntityItems @ [entity] )
+            this.MakeProjectAndDoWithProjectFile([], [], items.ToString(), (fun project fileName ->
+                // ensure things look right at start
+                let expect = Tree("References", ANYTREE,
+                             otherTreeMaker(
+                             Tree(entity.Caption(), Nil, Nil)))
+                TheTests.AssertSameTree(expect, project.FirstChild)
+                let foo = TheTests.FindNodeWithCaption(project, entity.Caption())
+                TheTests.EnsureMoveUpEnabled(foo)
+                // move it up
+                TheTests.MoveUp(foo)
+                // test that it moved up in solution explorer
+                let expect = Tree("References", ANYTREE,
+                             Tree(entity.Caption(), Nil,
+                             otherTreeMaker(Nil)))
+                TheTests.AssertSameTree(expect, project.FirstChild) 
+                // test that it moved up in MSBuild
+                SaveProject(project)
+                let fsprojFileText = File.ReadAllText(fileName)
+                printfn "%s" fsprojFileText
+                let expectedItems = MSBuildItems( [entity] @ otherEntityItems )
+                let regexStr = expectedItems.AsRegexString()
+                TheTests.HelpfulAssertMatches '<' regexStr fsprojFileText
+            ))
+
+    [<Test>]
+    member public this.``FsprojFileToSolutionExplorer.FileMovement.EntityCanBeMovedUpAboveFile``() =
+        this.``FsprojFileToSolutionExplorer.FileMovement.EntityCanBeMovedUpAbove``(this.SampleFileEntity)
+
+    [<Test>]
+    member public this.``FsprojFileToSolutionExplorer.FileMovement.EntityCanBeMovedUpAboveEmptyFolder``() =
+        this.``FsprojFileToSolutionExplorer.FileMovement.EntityCanBeMovedUpAbove``(this.SampleEmptyFolderEntity)
+
+    [<Test>]
+    member public this.``FsprojFileToSolutionExplorer.FileMovement.EntityCanBeMovedUpAboveFolderWithItems``() =
+        this.``FsprojFileToSolutionExplorer.FileMovement.EntityCanBeMovedUpAbove``(this.SampleFolderWithItemsEntity)
+
+    member public this.``FsprojFileToSolutionExplorer.FileMovement.EntityCanBeMovedDownBelow``(otherEntity) =
+        let (otherEntityItems, otherTreeMaker) = otherEntity
+        for entity in this.SampleEntities do
+            printfn "=========> testing moving %s" (entity.ToString())
+            let items = MSBuildItems( entity :: otherEntityItems )
+            this.MakeProjectAndDoWithProjectFile([], [], items.ToString(), (fun project fileName ->
+                // ensure things look right at start
+                let expect = Tree("References", ANYTREE,
+                             Tree(entity.Caption(), Nil,
+                             otherTreeMaker(Nil)))
+                TheTests.AssertSameTree(expect, project.FirstChild)
+                let foo = TheTests.FindNodeWithCaption(project, entity.Caption())
+                TheTests.EnsureMoveDownEnabled(foo)
+                // move it down
+                TheTests.MoveDown(foo)
+                // test that it moved down in solution explorer
+                let expect = Tree("References", ANYTREE,
+                             otherTreeMaker(
+                             Tree(entity.Caption(), Nil, Nil)))
+                TheTests.AssertSameTree(expect, project.FirstChild) 
+                // test that it moved down in MSBuild
+                SaveProject(project)
+                let fsprojFileText = File.ReadAllText(fileName)
+                printfn "%s" fsprojFileText
+                let expectedItems = MSBuildItems( otherEntityItems @ [entity] )
+                let regexStr = expectedItems.AsRegexString()
+                TheTests.HelpfulAssertMatches '<' regexStr fsprojFileText
+            ))
+
+    [<Test>]
+    member public this.``FsprojFileToSolutionExplorer.FileMovement.EntityCanBeMovedDownBelowFile``() =
+        this.``FsprojFileToSolutionExplorer.FileMovement.EntityCanBeMovedDownBelow``(this.SampleFileEntity)
+
+    [<Test>]
+    member public this.``FsprojFileToSolutionExplorer.FileMovement.EntityCanBeMovedDownBelowEmptyFolder``() =
+        this.``FsprojFileToSolutionExplorer.FileMovement.EntityCanBeMovedDownBelow``(this.SampleEmptyFolderEntity)
+
+    [<Test>]
+    member public this.``FsprojFileToSolutionExplorer.FileMovement.EntityCanBeMovedDownBelowFolderWithItems``() =
+        this.``FsprojFileToSolutionExplorer.FileMovement.EntityCanBeMovedDownBelow``(this.SampleFolderWithItemsEntity)
+
+    member public this.``FsprojFileToSolutionExplorer.FileMovement.FolderWithItemsCanBeMovedUpAbove``(otherEntity) =
+        let (otherEntityItems, otherTreeMaker) = otherEntity
+        let folderA = [CompileItem @"A\foo.fs"; CompileItem @"A\B\qux.fs"; FolderItem @"A\Empty\"; CompileItem @"A\zot.fs"]
+        let after = [CompileItem "after.fs"]
+        let items = MSBuildItems( otherEntityItems @ folderA @ after )
+        this.MakeProjectAndDoWithProjectFile([], [], items.ToString(), (fun project fileName ->
+            // ensure things look right at start
+            let expect = Tree("References", ANYTREE,
+                         otherTreeMaker(
+                         Tree("A", 
+                             Tree("foo.fs", Nil,
+                             Tree("B",
+                                 Tree("qux.fs", Nil, Nil),
+                             Tree("Empty", Nil,
+                             Tree("zot.fs", Nil, Nil)))),
+                         Tree("after.fs", Nil, Nil))))
+            TheTests.AssertSameTree(expect, project.FirstChild)
+            let foo = TheTests.FindNodeWithCaption(project, "A")
+            TheTests.EnsureMoveUpEnabled(foo)
+            // move it up
+            TheTests.MoveUp(foo)
+            // test that it moved up in solution explorer
+            let expect = Tree("References", ANYTREE,
+                         Tree("A", 
+                             Tree("foo.fs", Nil,
+                             Tree("B",
+                                 Tree("qux.fs", Nil, Nil),
+                             Tree("Empty", Nil,
+                             Tree("zot.fs", Nil, Nil)))),
+                         otherTreeMaker(
+                         Tree("after.fs", Nil, Nil))))
+            TheTests.AssertSameTree(expect, project.FirstChild) 
+            // test that it moved up in MSBuild
+            SaveProject(project)
+            let fsprojFileText = File.ReadAllText(fileName)
+            printfn "%s" fsprojFileText
+            let expectedItems = MSBuildItems( folderA @ otherEntityItems @ after )
+            let regexStr = expectedItems.AsRegexString()
+            TheTests.HelpfulAssertMatches '<' regexStr fsprojFileText
+        ))
+
+    [<Test>]
+    member public this.``FsprojFileToSolutionExplorer.FileMovement.FolderWithItemsCanBeMovedUpAboveFile``() =
+        this.``FsprojFileToSolutionExplorer.FileMovement.FolderWithItemsCanBeMovedUpAbove``(this.SampleFileEntity)
+
+    [<Test>]
+    member public this.``FsprojFileToSolutionExplorer.FileMovement.FolderWithItemsCanBeMovedUpAboveEmptyFolder``() =
+        this.``FsprojFileToSolutionExplorer.FileMovement.FolderWithItemsCanBeMovedUpAbove``(this.SampleEmptyFolderEntity)
+
+    [<Test>]
+    member public this.``FsprojFileToSolutionExplorer.FileMovement.FolderWithItemsCanBeMovedUpAboveFolderWithItems``() =
+        this.``FsprojFileToSolutionExplorer.FileMovement.FolderWithItemsCanBeMovedUpAbove``(this.SampleFolderWithItemsEntity)
+
+    member public this.``FsprojFileToSolutionExplorer.FileMovement.FolderWithItemsCanBeMovedDownBelow``(otherEntity) =
+        let (otherEntityItems, otherTreeMaker) = otherEntity
+        let folderA = [CompileItem @"A\foo.fs"; CompileItem @"A\B\qux.fs"; FolderItem @"A\Empty\"; CompileItem @"A\zot.fs"]
+        let after = [CompileItem "after.fs"]
+        let items = MSBuildItems( folderA @ otherEntityItems @ after )
+        this.MakeProjectAndDoWithProjectFile([], [], items.ToString(), (fun project fileName ->
+            // ensure things look right at start
+            let expect = Tree("References", ANYTREE,
+                         Tree("A", 
+                             Tree("foo.fs", Nil,
+                             Tree("B",
+                                 Tree("qux.fs", Nil, Nil),
+                             Tree("Empty", Nil,
+                             Tree("zot.fs", Nil, Nil)))),
+                         otherTreeMaker(
+                         Tree("after.fs", Nil, Nil))))
+            TheTests.AssertSameTree(expect, project.FirstChild)
+            let foo = TheTests.FindNodeWithCaption(project, "A")
+            TheTests.EnsureMoveDownEnabled(foo)
+            // move it down
+            TheTests.MoveDown(foo)
+            // test that it moved down in solution explorer
+            let expect = Tree("References", ANYTREE,
+                         otherTreeMaker(
+                         Tree("A", 
+                             Tree("foo.fs", Nil,
+                             Tree("B",
+                                 Tree("qux.fs", Nil, Nil),
+                             Tree("Empty", Nil,
+                             Tree("zot.fs", Nil, Nil)))),
+                         Tree("after.fs", Nil, Nil))))
+            TheTests.AssertSameTree(expect, project.FirstChild) 
+            // test that it moved down in MSBuild
+            SaveProject(project)
+            let fsprojFileText = File.ReadAllText(fileName)
+            printfn "%s" fsprojFileText
+            let expectedItems = MSBuildItems( otherEntityItems @ folderA @ after )
+            let regexStr = expectedItems.AsRegexString()
+            TheTests.HelpfulAssertMatches '<' regexStr fsprojFileText
+        ))
+
+    [<Test>]
+    member public this.``FsprojFileToSolutionExplorer.FileMovement.FolderWithItemsCanBeMovedDownBelowFile``() =
+        this.``FsprojFileToSolutionExplorer.FileMovement.FolderWithItemsCanBeMovedDownBelow``(this.SampleFileEntity)
+
+    [<Test>]
+    member public this.``FsprojFileToSolutionExplorer.FileMovement.FolderWithItemsCanBeMovedDownBelowEmptyFolder``() =
+        this.``FsprojFileToSolutionExplorer.FileMovement.FolderWithItemsCanBeMovedDownBelow``(this.SampleEmptyFolderEntity)
+
+    [<Test>]
+    member public this.``FsprojFileToSolutionExplorer.FileMovement.FolderWithItemsCanBeMovedDownBelowFolderWithItems``() =
+        this.``FsprojFileToSolutionExplorer.FileMovement.FolderWithItemsCanBeMovedDownBelow``(this.SampleFolderWithItemsEntity)
+
+    [<Test>]
+    member public this.``FsprojFileToSolutionExplorer.FileMovement.NegativeTests.EntityCannotBeMovedAboveReferences``() =
+        for entity in this.SampleEntities do
+            printfn "=========> testing moving %s" (entity.ToString())
+            let items = MSBuildItems [entity; CompileItem "bar.fs"]
+            use project = this.MakeProject([], [], items.ToString())
+            let expect = Tree("References", ANYTREE,
+                         Tree(entity.Caption(), Nil,
+                         Tree("bar.fs", Nil, Nil)))
+            TheTests.AssertSameTree(expect, project.FirstChild)
+            let foo = TheTests.FindNodeWithCaption(project, entity.Caption())
+            TheTests.EnsureMoveUpDisabled(foo)
+
+    [<Test>]
+    member public this.``FsprojFileToSolutionExplorer.FileMovement.NegativeTests.EntityCannotBeMovedUpWhenTopOfFolder``() =
+        for entity in this.SampleEntities |> List.map (fun e -> e.IntoFolder(@"Folder\")) do
+            printfn "=========> testing moving %s" (entity.ToString())
+            let items = MSBuildItems [FolderItem @"Folder\"; entity]
+            use project = this.MakeProject([], [], items.ToString())
+            let expect = Tree("References", ANYTREE,
+                         Tree("Folder",
+                            Tree(entity.Caption(), Nil, Nil), Nil))
+            TheTests.AssertSameTree(expect, project.FirstChild)
+            let bar = TheTests.FindNodeWithCaption(project, entity.Caption())
+            TheTests.EnsureMoveUpDisabled(bar)
+
+    [<Test>]
+    member public this.``FsprojFileToSolutionExplorer.FileMovement.NegativeTests.EntityCannotBeMovedDownWhenBottomOfFolder``() =
+        for entity in this.SampleEntities |> List.map (fun e -> e.IntoFolder(@"Folder\")) do
+            printfn "=========> testing moving %s" (entity.ToString())
+            let items = MSBuildItems [FolderItem @"Folder\"; entity]
+            use project = this.MakeProject([], [], items.ToString())
+            let expect = Tree("References", ANYTREE,
+                         Tree("Folder",
+                            Tree(entity.Caption(), Nil, Nil), Nil))
+            TheTests.AssertSameTree(expect, project.FirstChild)
+            let bar = TheTests.FindNodeWithCaption(project, entity.Caption())
+            TheTests.EnsureMoveDownDisabled(bar)
+
+    [<Test>]
+    member public this.``RenameFile.FailureToRenameInRDT.Bug616680.EnsureRevertToKnownConsistentState``() =
+        this.MakeProjectAndDo(["orig1.fs"], [], "", (fun project ->
+            let absFilePath = Path.Combine(project.ProjectFolder, "orig1.fs")
+            try
+                File.AppendAllText(absFilePath, "#light")
+                let orig1 = TheTests.FindNodeWithCaption(project, "orig1.fs")
+                VsMocks.vsRunningDocumentTableNextRenameDocumentCallThrows <- true
+                VsMocks.vsRunningDocumentTableFindAndLockDocumentVsHierarchyMock <- project
+                try
+                    ErrorHandler.ThrowOnFailure(orig1.SetEditLabel("orig2.fs")) |> ignore  // rename the file
+                    Assert.Fail("expected an exception")
+                with 
+                    | e -> printfn "Got expected exception: %s" e.Message
+                SaveProject(project)
+                // TODO ensure no events were fired
+                // ensure right in .fsproj
+                let msbuildInfo = TheTests.MsBuildCompileItems(project.BuildProject)
+                AssertEqual ["orig1.fs"] msbuildInfo
+                // ensure right in solution explorer
+                let expect = Tree("References", ANYTREE,
+                             Tree("orig1.fs", Nil, Nil))
+                TheTests.AssertSameTree(expect, project.FirstChild)
+            finally
+                File.Delete(absFilePath)
+            ))
+    
+    [<Test>]
+    member public this.``RenameFile.FailureToRenameInRDT.Bug616680.EnsureThatFileOrderDidNotChange``() =
+        this.MakeProjectAndDo(["a.fs";"b.fs";"orig1.fs";"c.fs";"d.fs"], [], "", (fun project ->
+            let absFilePath = Path.Combine(project.ProjectFolder, "orig1.fs")
+            try
+                File.AppendAllText(absFilePath, "#light")
+                let orig1 = TheTests.FindNodeWithCaption(project, "orig1.fs")
+                VsMocks.vsRunningDocumentTableNextRenameDocumentCallThrows <- true
+                VsMocks.vsRunningDocumentTableFindAndLockDocumentVsHierarchyMock <- project
+                try
+                    ErrorHandler.ThrowOnFailure(orig1.SetEditLabel("orig2.fs")) |> ignore  // rename the file
+                    Assert.Fail("expected an exception")
+                with 
+                    | e -> printfn "Got expected exception: %s" e.Message
+                SaveProject(project)
+                // TODO ensure no events were fired
+                // ensure right in .fsproj
+                let msbuildInfo = TheTests.MsBuildCompileItems(project.BuildProject)
+                AssertEqual ["a.fs";"b.fs";"orig1.fs";"c.fs";"d.fs"] msbuildInfo
+                // ensure right in solution explorer
+                let expect = Tree("References", ANYTREE,
+                             Tree("a.fs", Nil,
+                             Tree("b.fs", Nil,
+                             Tree("orig1.fs", Nil, 
+                             Tree("c.fs", Nil,
+                             Tree("d.fs", Nil, Nil))))))
+                TheTests.AssertSameTree(expect, project.FirstChild)
+            finally
+                File.Delete(absFilePath)
+            ))
+
+    [<Test>]
+    member public this.``RenameFile.VerifyItemIdsRemainsTheSame``() =
+        let name1 = "orig.fs"
+        let name2 = "orig2.fs"
+        this.MakeProjectAndDo([name1], [], "", (fun project ->
+            let absFilePath = Path.Combine(project.ProjectFolder, name1)
+            try
+                File.AppendAllText(absFilePath, "#light")
+                let orig1 = TheTests.FindNodeWithCaption(project, name1)
+                VsMocks.vsRunningDocumentTableFindAndLockDocumentVsHierarchyMock <- project
+                try
+                    ErrorHandler.ThrowOnFailure(orig1.SetEditLabel(name2)) |> ignore  // rename the file
+                with 
+                    | e -> Assert.Fail("no exception expected")
+
+                let orig2 = TheTests.FindNodeWithCaption(project, name2)
+                AssertEqual orig1.ID orig2.ID
+                
+            finally
+                File.Delete(absFilePath)
+            ))
+    
+    [<Test>]
+    member public this.``RenameFile.MainlineSuccessCase``() =
+        this.MakeProjectAndDo(["orig1.fs"], [], "", (fun project ->
+            let absFilePath = Path.Combine(project.ProjectFolder, "orig1.fs")
+            try
+                File.AppendAllText(absFilePath, "#light")
+                let orig1 = TheTests.FindNodeWithCaption(project, "orig1.fs")
+                VsMocks.vsRunningDocumentTableFindAndLockDocumentVsHierarchyMock <- project
+                try
+                    ErrorHandler.ThrowOnFailure(orig1.SetEditLabel("orig2.fs")) |> ignore  // rename the file
+                with 
+                    | e -> Assert.Fail("no exception expected")
+                SaveProject(project)
+                // TODO ensure IVsHierarchyEvents Delete/Add was fired
+                // TODO ensure IVsTrackProjectDocumentsEvents Renamed was fired
+                // ensure right in .fsproj
+                let msbuildInfo = TheTests.MsBuildCompileItems(project.BuildProject)
+                AssertEqual ["orig2.fs"] msbuildInfo
+                // ensure right in solution explorer
+                let expect = Tree("References", ANYTREE,
+                             Tree("orig2.fs", Nil, Nil))
+                TheTests.AssertSameTree(expect, project.FirstChild)
+            finally
+                File.Delete(absFilePath)
+            ))
+    
+    [<Test>]
+    member public this.``RenameFile.BuildActionIsResetBasedOnFilenameExtension``() =
+        let GetTextFromBuildAction (action:VSLangProj.prjBuildAction) =
+            match action with
+            | VSLangProj.prjBuildAction.prjBuildActionCompile -> "Compile"
+            | VSLangProj.prjBuildAction.prjBuildActionContent -> "Content"
+            | VSLangProj.prjBuildAction.prjBuildActionEmbeddedResource -> "EmbeddedResource"
+            |_ -> "None"
+        let COMPILE = "Compile"
+        let NONE = "None"
+        let EMBEDDEDRESOURCE = "EmbeddedResource"
+        let CONTENT = "Content"
+        // briefly, we just want out-of-the-box defaults to be like C#, with simpler logic, so we just hardcode a few values to be like C# and then otherwise default to NONE
+        let defaultBuildActionTable = dict [ "config", CONTENT
+                                             "css", CONTENT
+                                             "map", CONTENT
+                                             "manifest", NONE
+                                             "bmp", CONTENT
+                                             "cd", NONE
+                                             "cur", CONTENT
+                                             "xsd", NONE
+                                             "ico", CONTENT
+                                             "js", CONTENT
+                                             "sync", NONE
+                                             "tt", NONE
+                                             "resx", EMBEDDEDRESOURCE
+                                             "ruleset", NONE
+                                             "settings", NONE
+                                             "txt", CONTENT
+                                             "wsf", CONTENT
+                                             "xml", CONTENT
+                                             "ml", COMPILE
+                                             "mli", COMPILE
+                                             "fs", COMPILE
+                                             "fsi", COMPILE
+                                             "fsx", NONE
+                                             "fsscript", NONE
+                                             "someunexpectedgobbledegook", NONE ]
+        // A rename that changes a file extension will pop up a modal dialog box, this tells the mock to say 'yes' to the dialog
+        VsMocks.vsUIShellShowMessageBoxResult <- Some 6 // IDYES = 6
+
+        this.MakeProjectAndDo(["foo.fs"], [], "", (fun project ->
+            let Absolutize filename = Path.Combine(project.ProjectFolder, filename)
+            let mutable currentAbsoluteFilePath = Absolutize "foo.fs"
+            File.AppendAllText(currentAbsoluteFilePath, "// dummy content")
+            try
+                for KeyValue(extension, buildAction) in defaultBuildActionTable do
+                    let node = TheTests.FindNodeWithCaption(project, Path.GetFileName(currentAbsoluteFilePath))
+                    let newFileName = Absolutize("foo." + extension)
+                    VsMocks.vsRunningDocumentTableFindAndLockDocumentVsHierarchyMock <- project
+                    try
+                        ErrorHandler.ThrowOnFailure(node.SetEditLabel(Path.GetFileName(newFileName))) |> ignore  // rename the file
+                    with 
+                        | e -> Assert.Fail("no exception expected, but got " + e.ToString())
+                    
+                    // check that the OM has the updated build action
+                    let node = TheTests.FindNodeWithCaption(project, Path.GetFileName(newFileName)) :?> FSharpFileNode
+                    let props = node.NodeProperties :?> FSharpFileNodeProperties 
+                    AssertEqual buildAction (GetTextFromBuildAction props.BuildAction)
+                    
+                    // check that the build action in the .fsproj file has the expected value
+                    SaveProject(project)
+                    let fsprojFileText = File.ReadAllText(Absolutize project.ProjectFile)
+                    printfn "%s" fsprojFileText
+                    let expectedRegexStr = "<" + buildAction + " Include=\"" + Path.GetFileName(newFileName) + "\" />"
+                    TheTests.HelpfulAssertMatches '<' expectedRegexStr fsprojFileText
+                    
+                    currentAbsoluteFilePath <- newFileName
+            finally
+                VsMocks.vsUIShellShowMessageBoxResult <- None
+                File.Delete(currentAbsoluteFilePath) 
+        ))
+
+
+
+    [<Test>]
+    member public this.``FsprojOutputWindow.ErrorOriginColumnsAreBase1``() =
+        let (outputWindowPaneErrors : string list ref) = ref [] // output window pane errors
+        let vso = VsMocks.vsOutputWindowPane(outputWindowPaneErrors)
+        let compileItem = ["foo.fs"]
+        let expectedError = "foo\.fs\(1,1\): error FS0039: The value or constructor 'bar' is not defined." // expected error
+        
+        DoWithTempFile "Test.fsproj" (fun projFile ->
+            File.AppendAllText(projFile, TheTests.SimpleFsprojText(compileItem, [], ""))
+            use project = TheTests.CreateProject(projFile)
+            let srcFile = (Path.GetDirectoryName projFile) + "\\" + "foo.fs"
+            File.AppendAllText(srcFile, "bar") ; // foo.fs will be cleaned up by parent call to DoWithTempFile
+            project.BuildToOutput("Build", vso) |> ignore // Build the project using vso as the output logger
+        
+            let errors = List.filter (fun s -> (new Regex(expectedError)).IsMatch(s)) !outputWindowPaneErrors
+        
+            for e in errors do
+                printfn "Output Window Pane Error: %s" e
+                
+            // there should be one and only one error for 'bar', located at (1,1)
+            AssertEqual (List.length errors) 1
+        )
+
+    [<Test>]
+    member public this.``FsprojOutputWindow.HighUnicodeCharactersAreProperlyDisplayed``() =
+        let (outputWindowPaneErrors : string list ref) = ref [] // output window pane errors
+        let vso = VsMocks.vsOutputWindowPane(outputWindowPaneErrors)
+        let compileItem = ["新規bcrogram.fs"]
+        let expectedError = "新規bcrogram\.fs\(1,1\): error FS0039: The value or constructor 'bar' is not defined." // expected error
+        
+        DoWithTempFile "Test.fsproj" (fun projFile ->
+            File.AppendAllText(projFile, TheTests.SimpleFsprojText(compileItem, [], ""))
+            use project = TheTests.CreateProjectWithUTF8Output(projFile)
+            let srcFile = (Path.GetDirectoryName projFile) + "\\" + "新規bcrogram.fs"
+            File.AppendAllText(srcFile, "bar") ; // 新規bcrogram.fs will be cleaned up by parent call to DoWithTempFile
+            project.BuildToOutput("Build", vso) |> ignore // Build the project using vso as the output logger
+            let errors = List.filter (fun s -> (new Regex(expectedError)).IsMatch(s)) !outputWindowPaneErrors
+        
+            for e in errors do  
+                printfn "Output Window Pane Error: %s" e
+                
+            // there should be one and only one error for 'bar', located at (1,1)
+            AssertEqual (List.length errors) 1
+            ()
+        )
diff --git a/vsintegration/src/unittests/Tests.ProjectSystem.ProjectItems.fs b/vsintegration/src/unittests/Tests.ProjectSystem.ProjectItems.fs
new file mode 100644
index 0000000..f871188
--- /dev/null
+++ b/vsintegration/src/unittests/Tests.ProjectSystem.ProjectItems.fs
@@ -0,0 +1,165 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+namespace UnitTests.Tests.ProjectSystem
+
+open System
+open System.IO
+open NUnit.Framework
+open UnitTests.TestLib.Utils.Asserts
+open UnitTests.TestLib.ProjectSystem
+open Microsoft.VisualStudio.FSharp.ProjectSystem
+
+
+[<TestFixture>]
+type ProjectItems() = 
+    inherit TheTests()
+    
+    //TODO: look for a way to remove the helper functions
+    static let ANYTREE = Tree("",Nil,Nil)
+
+    [<Test>]
+    member public this.``RemoveAssemblyReference.NoIVsTrackProjectDocuments2Events``() =
+        this.MakeProjectAndDo(["file.fs"], ["System.Numerics"],"", (fun project ->
+            let listener = project.Site.GetService(typeof<Salsa.VsMocks.IVsTrackProjectDocuments2Listener>) :?> Salsa.VsMocks.IVsTrackProjectDocuments2Listener
+            project.ComputeSourcesAndFlags()
+
+            let containsSystemNumerics () = 
+                project.GetCompileFlags()
+                |> Seq.exists (fun f -> f.IndexOf("System.Numerics") <> -1)
+
+            let wasCalled = ref false
+            Assert.IsTrue(containsSystemNumerics (), "Project should contains reference to System.Numerics")
+
+            let refContainer = project.GetReferenceContainer()
+            let reference = 
+                refContainer.EnumReferences() 
+                |> Seq.find(fun r -> r.SimpleName = "System.Numerics")
+            (
+                use _guard = listener.OnAfterRemoveFiles.Subscribe(fun _ -> wasCalled := true)
+                reference.Remove(false)
+            )
+
+            Assert.IsFalse(!wasCalled, "No events from IVsTrackProjectDocuments2 are expected")
+            Assert.IsFalse(containsSystemNumerics(), "Project should not contains reference to System.Numerics")            
+            ))
+
+    [<Test>]
+    member public this.``AddNewItem.ItemAppearsAtBottomOfFsprojFile``() =
+        this.MakeProjectAndDo(["orig.fs"], [], "", (fun project ->
+            let absFilePath = Path.Combine(project.ProjectFolder, "a.fs")
+            try
+                File.AppendAllText(absFilePath, "#light")
+                // Note: this is not the same code path as the UI, but it is close
+                project.MoveNewlyAddedFileToBottomOfGroup (fun () ->
+                    project.AddNewFileNodeToHierarchy(project,absFilePath) |> ignore)
+                let msbuildInfo = TheTests.MsBuildCompileItems(project.BuildProject)
+                AssertEqual ["orig.fs"; "a.fs"] msbuildInfo
+            finally
+                File.Delete(absFilePath)
+            ))
+
+    [<Test>]
+    member public this.``AddNewItem.ToAFolder.ItemAppearsAtBottomOfFolder``() =
+        this.MakeProjectAndDo(["orig.fs"; "Folder\\f1.fs"; "Folder\\f2.fs"; "final.fs"], [], "", (fun project ->
+            let dir = Path.Combine(project.ProjectFolder, "Folder")
+            Directory.CreateDirectory(dir) |> ignore
+            let absFilePath = Path.Combine(dir, "a.fs")
+            try
+                File.AppendAllText(absFilePath, "#light")
+                // Note: this is not the same code path as the UI, but it is close
+                project.MoveNewlyAddedFileToBottomOfGroup (fun () ->
+                    project.AddNewFileNodeToHierarchy(project.FindChild("Folder"),absFilePath) |> ignore)
+                let msbuildInfo = TheTests.MsBuildCompileItems(project.BuildProject)
+                AssertEqual ["orig.fs"; "Folder\\f1.fs"; "Folder\\f2.fs"; "Folder\\a.fs"; "final.fs"] msbuildInfo
+            finally
+                File.Delete(absFilePath)
+            ))
+    
+    [<Test>]
+    member public this.``AddNewItem.ItemAppearsAtBottomOfFsprojFileEvenIfUnknownItemWithSameName``() =
+        this.MakeProjectAndDo([], [], @"
+                <ItemGroup>
+                    <Unknown Include=""a.fs"" />
+                    <Compile Include=""orig.fs"" />
+                </ItemGroup>
+            ", (fun project ->
+            let absFilePath = Path.Combine(project.ProjectFolder, "a.fs")
+            try
+                File.AppendAllText(absFilePath, "#light")
+                // Note: this is not the same code path as the UI, but it is close
+                project.MoveNewlyAddedFileToBottomOfGroup (fun () ->
+                    project.AddNewFileNodeToHierarchy(project,absFilePath) |> ignore)
+                let msbuildInfo = TheTests.MsBuildCompileItems(project.BuildProject)
+                AssertEqual ["orig.fs"; "a.fs"] msbuildInfo
+            finally
+                File.Delete(absFilePath)
+            ))
+    
+    [<Test>]
+    member public this.``AddNewItemBelow.ItemAppearsInRightSpot``() =
+        this.MakeProjectAndDo(["orig1.fs"; "orig2.fs"], [], "", (fun project ->
+            let absFilePath = Path.Combine(project.ProjectFolder, "new.fs")
+            try
+                File.AppendAllText(absFilePath, "#light")
+                // Note: this is not the same code path as the UI, but it is close
+                let orig1 = TheTests.FindNodeWithCaption(project, "orig1.fs")
+                project.MoveNewlyAddedFileBelow (orig1, fun () ->
+                    project.AddNewFileNodeToHierarchy(project,absFilePath) |> ignore)
+                // ensure right in .fsproj
+                let msbuildInfo = TheTests.MsBuildCompileItems(project.BuildProject)
+                AssertEqual ["orig1.fs"; "new.fs"; "orig2.fs"] msbuildInfo
+                // ensure right in solution explorer
+                let expect = Tree("References", ANYTREE,
+                             Tree("orig1.fs", Nil,
+                             Tree("new.fs", Nil,
+                             Tree("orig2.fs", Nil, Nil))))
+                TheTests.AssertSameTree(expect, project.FirstChild)
+            finally
+                File.Delete(absFilePath)
+            ))
+    
+    [<Test>]
+    member public this.``AddNewItemAbove.ItemAppearsInRightSpot.Case1``() =
+        this.MakeProjectAndDo(["orig1.fs"; "orig2.fs"], [], "", (fun project ->
+            let absFilePath = Path.Combine(project.ProjectFolder, "new.fs")
+            try
+                File.AppendAllText(absFilePath, "#light")
+                // Note: this is not the same code path as the UI, but it is close
+                let orig2 = TheTests.FindNodeWithCaption(project, "orig2.fs")
+                project.MoveNewlyAddedFileAbove (orig2, fun () ->
+                    project.AddNewFileNodeToHierarchy(project,absFilePath) |> ignore)
+                // ensure right in .fsproj
+                let msbuildInfo = TheTests.MsBuildCompileItems(project.BuildProject)
+                AssertEqual ["orig1.fs"; "new.fs"; "orig2.fs"] msbuildInfo
+                // ensure right in solution explorer
+                let expect = Tree("References", ANYTREE,
+                             Tree("orig1.fs", Nil,
+                             Tree("new.fs", Nil,
+                             Tree("orig2.fs", Nil, Nil))))
+                TheTests.AssertSameTree(expect, project.FirstChild)
+            finally
+                File.Delete(absFilePath)
+            ))
+    
+    [<Test>]
+    member public this.``AddNewItemAbove.ItemAppearsInRightSpot.Case2``() =
+        this.MakeProjectAndDo(["orig1.fs"; "orig2.fs"], [], "", (fun project ->
+            let absFilePath = Path.Combine(project.ProjectFolder, "new.fs")
+            try
+                File.AppendAllText(absFilePath, "#light")
+                // Note: this is not the same code path as the UI, but it is close
+                let orig1 = TheTests.FindNodeWithCaption(project, "orig1.fs")
+                project.MoveNewlyAddedFileAbove (orig1, fun () ->
+                    project.AddNewFileNodeToHierarchy(project,absFilePath) |> ignore)
+                // ensure right in .fsproj
+                let msbuildInfo = TheTests.MsBuildCompileItems(project.BuildProject)
+                AssertEqual ["new.fs"; "orig1.fs"; "orig2.fs"] msbuildInfo
+                // ensure right in solution explorer
+                let expect = Tree("References", ANYTREE,
+                             Tree("new.fs", Nil,
+                             Tree("orig1.fs", Nil,
+                             Tree("orig2.fs", Nil, Nil))))
+                TheTests.AssertSameTree(expect, project.FirstChild)
+            finally
+                File.Delete(absFilePath)
+            ))
diff --git a/vsintegration/src/unittests/Tests.ProjectSystem.References.fs b/vsintegration/src/unittests/Tests.ProjectSystem.References.fs
new file mode 100644
index 0000000..9d26f2a
--- /dev/null
+++ b/vsintegration/src/unittests/Tests.ProjectSystem.References.fs
@@ -0,0 +1,621 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+namespace UnitTests.Tests.ProjectSystem
+
+open System
+open System.Collections.Generic
+open System.IO
+open System.Reflection
+
+open NUnit.Framework
+open Salsa
+open UnitTests.TestLib.Utils.Asserts
+open UnitTests.TestLib.Utils.FilesystemHelpers
+open UnitTests.TestLib.ProjectSystem
+
+open Microsoft.VisualStudio.FSharp.ProjectSystem
+open Microsoft.VisualStudio.Shell.Interop
+open Microsoft.Win32
+
+[<TestFixture>]
+type References() = 
+    inherit TheTests()
+
+    //TODO: look for a way to remove the helper functions
+    static let Net35RefAssemPathOnThisMachine() =
+        let key = @"SOFTWARE\Microsoft\.NETFramework\AssemblyFolders\Microsoft .NET Framework 3.5 Reference Assemblies"
+        let hklm = Registry.LocalMachine
+        let rkey = hklm.OpenSubKey(key)
+        rkey.GetValue("") :?> string
+    static let Net20AssemExPathOnThisMachine() =
+        let key = @"SOFTWARE\Microsoft\.NETFramework\v2.0.50727\AssemblyFoldersEx\Public Assemblies (Common Files)"
+        let hklm = Registry.LocalMachine
+        let rkey = hklm.OpenSubKey(key)
+        rkey.GetValue("") :?> string
+
+    /////////////////////////////////
+    // project helpers
+    static let SaveProject(project : UnitTestingFSharpProjectNode) =
+        project.Save(null, 1, 0u) |> ignore
+
+    static let DefaultBuildActionOfFilename(filename) : Salsa.BuildAction = 
+        match Path.GetExtension(filename) with 
+        | ".fsx" -> Salsa.BuildAction.None
+        | ".resx"
+        | ".resources" -> Salsa.BuildAction.EmbeddedResource
+        | _ -> Salsa.BuildAction.Compile            
+
+    static let GetReferenceContainerNode(project : ProjectNode) =
+        let l = new List<ReferenceContainerNode>()
+        project.FindNodesOfType(l)
+        l.[0]  
+
+
+    [<Test>]
+    member this.``BasicAssemblyReferences1``() =
+        this.MakeProjectAndDo([], ["System"], "", (fun proj ->
+            let systemRef = proj.FirstChild.FirstChild :?> AssemblyReferenceNode
+            Assert.IsTrue(systemRef.CanShowDefaultIcon())
+        ))
+
+    [<Test>]
+    member this.``BasicAssemblyReferences2``() =
+        this.MakeProjectAndDo([], ["System.Net"], "", (fun proj ->
+            let systemRef = proj.FirstChild.FirstChild :?> AssemblyReferenceNode
+            Assert.IsTrue(systemRef.CanShowDefaultIcon())
+        ))
+            
+    [<Test>]
+    member public this.``AddReference.StarredAssemblyName`` () = 
+        DoWithTempFile "Test.fsproj" (fun projFile ->
+            File.AppendAllText(projFile, TheTests.SimpleFsprojText([], [], ""))
+            use project = TheTests.CreateProject(projFile) 
+            let assName = new AssemblyName(typeof<System.Windows.Forms.Form>.Assembly.FullName)
+            let selectorData = new VSCOMPONENTSELECTORDATA(``type`` = VSCOMPONENTTYPE.VSCOMPONENTTYPE_ComPlus, bstrFile = "*" + assName.FullName)
+            let refContainer = GetReferenceContainerNode(project)
+            refContainer.AddReferenceFromSelectorData(selectorData) |> Assert.IsNotNull
+            let l = new List<AssemblyReferenceNode>()
+            project.FindNodesOfType(l)
+            Assert.AreEqual(1, l.Count)
+            Assert.AreEqual("System.Windows.Forms", l.[0].Caption)            
+            SaveProject(project)
+            let fsprojFileText = File.ReadAllText(project.FileName)
+            printfn "%s" fsprojFileText
+            let expectedFsprojRegex = @"<Reference Include=""System.Windows.Forms"" />"
+            TheTests.HelpfulAssertMatches '<' expectedFsprojRegex fsprojFileText
+            )
+
+    [<Test>]
+    member public this.``References.Bug787899.AddDuplicateUnresolved``() =
+        // Let's create a run-of-the-mill project just to have a spare assembly around
+        this.CreateDummyTestProjectBuildItAndDo(fun exe ->
+            Assert.IsTrue(File.Exists exe, "failed to build exe")
+            this.MakeProjectAndDoWithProjectFile(["doesNotMatter.fs"], ["mscorlib"; "System"; "System.Core"; "System.Net"], 
+                                                    "<ItemGroup><Reference Include=\"Test\"><HintPath>.\\Test.dll</HintPath></Reference></ItemGroup>", "v3.5", (fun project file ->
+                let assemRef = TheTests.FindNodeWithCaption(project, "Test") :?> AssemblyReferenceNode
+                Assert.IsFalse(assemRef.CanShowDefaultIcon(), "reference should be banged out, does not resolve")
+                // add reference to Test.exe
+                let selectorData = new VSCOMPONENTSELECTORDATA(``type`` = VSCOMPONENTTYPE.VSCOMPONENTTYPE_File, bstrFile = exe)
+                let refContainer = GetReferenceContainerNode(project)
+                refContainer.AddReferenceFromSelectorData(selectorData) |> (fun x -> Assert.IsNotNull(x, "expected AddReference to succeed"))
+                // it should have succeeded (no throw)
+                ))
+            )
+
+    [<Test>]
+    member public this.``References.Bug787899.AddDuplicateResolved``() =
+        // Let's create a run-of-the-mill project just to have a spare assembly around
+        this.CreateDummyTestProjectBuildItAndDo(fun exe ->
+            Assert.IsTrue(File.Exists exe, "failed to build exe")
+            this.MakeProjectAndDoWithProjectFile(["doesNotMatter.fs"], ["mscorlib"; "System"; "System.Core"; "System.Net"], 
+                                                    sprintf "<ItemGroup><Reference Include=\"Test\"><HintPath>%s</HintPath></Reference></ItemGroup>" exe, "v3.5", (fun project file ->
+                let assemRef = TheTests.FindNodeWithCaption(project, "Test") :?> AssemblyReferenceNode
+                Assert.IsTrue(assemRef.CanShowDefaultIcon(), "reference should not be banged out, does resolve")
+                // add reference to Test.exe
+                let selectorData = new VSCOMPONENTSELECTORDATA(``type`` = VSCOMPONENTTYPE.VSCOMPONENTTYPE_File, bstrFile = exe)
+                let refContainer = GetReferenceContainerNode(project)
+                try
+                    refContainer.AddReferenceFromSelectorData(selectorData) |> ignore
+                    Assert.Fail("expected AddReference to Fail")
+                with :? InvalidOperationException as e ->
+                    Assert.AreEqual("A reference to 'Test' (with assembly name 'Test') could not be added. A reference to the component 'Test' with the same assembly name already exists in the project.", e.Message)
+                ))
+            )
+
+    [<Test>]
+    member public this.``ReferenceResolution.Bug4423.LoadedFsProj.Works``() =
+        this.MakeProjectAndDo(["doesNotMatter.fs"], ["mscorlib"; "System"; "System.Core"; "System.Net"], "", "v3.5", (fun project ->
+            let expectedRefInfo = [ "mscorlib", true
+                                    "System", true
+                                    "System.Core", true
+                                    "System.Net", true ]
+            let refContainer = GetReferenceContainerNode(project)
+            let actualRefInfo = [
+                let r = ref(refContainer.FirstChild :?> ReferenceNode)
+                while !r <> null do
+                    yield ((!r).Caption, ((!r).CanShowDefaultIcon()))
+                    r := (!r).NextSibling :?> ReferenceNode
+                ]
+            AssertEqual expectedRefInfo actualRefInfo
+            ))
+
+
+    [<Test>]
+    member public this.``ReferenceResolution.Bug4423.LoadedFsProj.WithExactDuplicates``() =
+        this.MakeProjectAndDo(["doesNotMatter.fs"], ["System"; "System"], "", "v3.5", (fun project ->
+            let expectedRefInfo = [ "System", true  // In C#, one will be banged out, whereas
+                                    "System", true] // one will be ok, but in F# both show up as ok.  Bug?  Not worth the effort to fix.
+            let refContainer = GetReferenceContainerNode(project)
+            let actualRefInfo = [
+                let r = ref(refContainer.FirstChild :?> ReferenceNode)
+                while !r <> null do
+                    yield ((!r).Caption, ((!r).CanShowDefaultIcon()))
+                    r := (!r).NextSibling :?> ReferenceNode
+                ]
+            AssertEqual expectedRefInfo actualRefInfo
+            ))
+
+    [<Test>]
+    member public this.``ReferenceResolution.Bug4423.LoadedFsProj.WithBadDuplicates``() =
+        this.MakeProjectAndDo(["doesNotMatter.fs"], ["System"; "System.dll"], "", "v3.5", (fun project ->
+            let expectedRefInfo = [ "System", false     // one will be banged out
+                                    "System.dll", true] // one will be ok
+            let refContainer = GetReferenceContainerNode(project)
+            let actualRefInfo = [
+                let r = ref(refContainer.FirstChild :?> ReferenceNode)
+                while !r <> null do
+                    yield ((!r).Caption, ((!r).CanShowDefaultIcon()))
+                    r := (!r).NextSibling :?> ReferenceNode
+                ]
+            AssertEqual expectedRefInfo actualRefInfo
+            ))
+
+    [<Test>]
+    member public this.``ReferenceResolution.Bug4423.LoadedFsProj.WorksWithFilenames``() =
+        let edte = Path.Combine(Net20AssemExPathOnThisMachine(), "EnvDTE80.dll")
+        let ssmw = Path.Combine(Net35RefAssemPathOnThisMachine(), "System.ServiceModel.Web.dll")
+        this.MakeProjectAndDo(["doesNotMatter.fs"], [edte; ssmw], "", "v3.5", (fun project ->
+            let expectedRefInfo = [ edte, true 
+                                    ssmw, true ]
+            let refContainer = GetReferenceContainerNode(project)
+            let actualRefInfo = [
+                let r = ref(refContainer.FirstChild :?> ReferenceNode)
+                while !r <> null do
+                    yield ((!r).Caption, ((!r).CanShowDefaultIcon()))
+                    r := (!r).NextSibling :?> ReferenceNode
+                ]
+            AssertEqual expectedRefInfo actualRefInfo
+            ))
+
+    [<Test>]
+    member public this.``ReferenceResolution.Bug4423.LoadedFsProj.WeirdCases``() =
+        this.MakeProjectAndDo(["doesNotMatter.fs"], ["mscorlib, Version=4.0.0.0"; "System, Version=4.0.0.0"; "System.Core, Version=4.0.0.0"; "System.Net, Version=4.0.0.0"], "", "v4.0", (fun project ->
+            let expectedRefInfo = [ "mscorlib", true
+                                    "System", true
+                                    "System.Core, Version=4.0.0.0", false // msbuild does funny things for System.Core (TODO bug number)
+                                    "System.Net", true ]
+            let refContainer = GetReferenceContainerNode(project)
+            let actualRefInfo = [
+                let r = ref(refContainer.FirstChild :?> ReferenceNode)
+                while !r <> null do
+                    yield ((!r).Caption, ((!r).CanShowDefaultIcon()))
+                    r := (!r).NextSibling :?> ReferenceNode
+                ]
+            AssertEqual expectedRefInfo actualRefInfo
+            ))
+
+    member public this.ReferenceResolutionHelper(tab : AddReferenceDialogTab, fullPath : string, expectedFsprojRegex : string) =
+        this.ReferenceResolutionHelper(tab, fullPath, expectedFsprojRegex, "v3.5", [])
+        
+    member public this.ReferenceResolutionHelper(tab : AddReferenceDialogTab, fullPath : string, expectedFsprojRegex : string, targetFrameworkVersion : string, originalReferences : string list) =
+        // Trace.Log <- "ProjectSystemReferenceResolution" // can be useful
+        this.MakeProjectAndDo(["doesNotMatter.fs"], originalReferences, "", targetFrameworkVersion, (fun project ->
+            let cType = match tab with
+                        | AddReferenceDialogTab.DotNetTab -> VSCOMPONENTTYPE.VSCOMPONENTTYPE_ComPlus
+                        | AddReferenceDialogTab.BrowseTab -> VSCOMPONENTTYPE.VSCOMPONENTTYPE_File
+                        | _ -> failwith "unexpected"
+            let selectorData = new VSCOMPONENTSELECTORDATA(``type`` = cType, bstrFile = fullPath)
+            let refContainer = GetReferenceContainerNode(project)
+            refContainer.AddReferenceFromSelectorData(selectorData) |> Assert.IsNotNull
+            SaveProject(project)
+            let fsprojFileText = File.ReadAllText(project.FileName)
+            printfn "%s" fsprojFileText
+            TheTests.HelpfulAssertMatches '<' expectedFsprojRegex fsprojFileText
+            ))
+
+    [<Test>]
+    member public this.``ReferenceResolution.Bug4423.FxAssembly.NetTab.AddDuplicate1``() =
+        try
+            this.ReferenceResolutionHelper(AddReferenceDialogTab.DotNetTab, 
+                                           Path.Combine(Net35RefAssemPathOnThisMachine(), "System.ServiceModel.Web.dll"), 
+                                           @"whatever, expectation does not matter, will throw before then",
+                                           "v3.5",
+                                           ["System.ServiceModel.Web"])  // assembly name
+            Assert.Fail("adding a duplicate reference should have failed")
+        with e ->                                           
+            TheTests.HelpfulAssertMatches ' ' "A reference to '.*' \\(with assembly name '.*'\\) could not be added. A reference to the component '.*' with the same assembly name already exists in the project." e.Message
+
+
+    // see 5491 [<Test>]
+    member public this.``ReferenceResolution.Bug4423.FxAssembly.NetTab.AddDuplicate2``() =
+        try
+            this.ReferenceResolutionHelper(AddReferenceDialogTab.DotNetTab, 
+                                           Path.Combine(Net35RefAssemPathOnThisMachine(), "System.ServiceModel.Web.dll"), 
+                                           @"whatever, expectation does not matter, will throw before then",
+                                           "v3.5",
+                                           ["System.ServiceModel.Web.dll"]) // filename
+            Assert.Fail("adding a duplicate reference should have failed")
+        with e ->                                           
+            TheTests.HelpfulAssertMatches ' ' "A reference to '.*' could not be added. A reference to the component '.*' already exists in the project." e.Message
+
+    [<Test>]
+    member public this.``ReferenceResolution.Bug4423.FxAssembly.NetTab``() =
+        this.ReferenceResolutionHelper(AddReferenceDialogTab.DotNetTab, 
+                                       Path.Combine(Net35RefAssemPathOnThisMachine(), "System.ServiceModel.Web.dll"), 
+                                       // TODO the intent here is to match whatever C# does; below is a snapshot from July 7, 2009
+                                       @"<Reference Include=""System.ServiceModel.Web"" />")
+
+    [<Test>]
+    member public this.``ReferenceResolution.Bug4423.FxAssembly.BrowseTab.SameVersion``() =
+        let sysCoreRefAssemPath = Path.Combine(Net35RefAssemPathOnThisMachine(), "System.ServiceModel.Web.dll")
+        let dirName = Path.GetTempPath()
+        let copy = Path.Combine(dirName, "System.ServiceModel.Web.dll")
+        try
+            File.Copy(sysCoreRefAssemPath, copy, true)
+            this.ReferenceResolutionHelper(AddReferenceDialogTab.BrowseTab, 
+                                           copy,
+                                           // TODO the intent here is to match whatever C# does; below is a snapshot from July 7, 2009
+                                           @"<Reference Include=""System.ServiceModel.Web"" />")
+        finally
+            File.Delete(copy)
+
+    [<Test>]
+    member public this.``ReferenceResolution.Bug4423.FxAssembly.BrowseTab.DifferentVersion``() =
+        let sysCoreRefAssemPath = Path.Combine(Net35RefAssemPathOnThisMachine(), "System.ServiceModel.Web.dll")
+        let dirName = Path.GetTempPath()
+        let copy = Path.Combine(dirName, "System.ServiceModel.Web.dll")
+        try
+            File.Copy(sysCoreRefAssemPath, copy, true)
+            this.ReferenceResolutionHelper(AddReferenceDialogTab.BrowseTab, 
+                                           copy,
+                                           // TODO the intent here is to match whatever C# does; below is a snapshot from July 7, 2009
+                                           @"<Reference Include=""System.ServiceModel.Web"" />",
+                                           "v4.0",  // TargetFramework is 4.0, but browsing to 3.5 reference assembly
+                                           [])
+        finally
+            File.Delete(copy)
+    
+    [<Test>]
+    member public this.``ReferenceResolution.NonFxAssembly.SeveralCandidates``() =
+        let fsharp4300, fsharp4310 = 
+            let root = Path.Combine(FSharpSDKHelper.FSharpReferenceAssembliesLocation, FSharpSDKHelper.NETFramework, FSharpSDKHelper.v40)
+            Path.Combine(root, "4.3.0.0", "FSharp.Core.dll"),Path.Combine(root, "4.3.1.0", "FSharp.Core.dll")
+        
+        this.ReferenceResolutionHelper
+            (
+                AddReferenceDialogTab.DotNetTab, 
+                fsharp4300,  
+                @"<Reference Include=""FSharp.Core, Version=4\.3\.0\.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"" />",
+                "v4.5",
+                []
+            )
+        this.ReferenceResolutionHelper
+            (
+                AddReferenceDialogTab.DotNetTab, 
+                fsharp4310,  
+                @"<Reference Include=""FSharp.Core, Version=4\.3\.1\.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"" />",
+                "v4.5",
+                []
+            )
+        this.ReferenceResolutionHelper
+            (
+                AddReferenceDialogTab.BrowseTab, 
+                fsharp4300,  
+                @"4\.3\.0\.0\\FSharp\.Core\.dll</HintPath>", 
+                "v4.5",
+                []
+            )
+        this.ReferenceResolutionHelper
+            (
+                AddReferenceDialogTab.BrowseTab, 
+                fsharp4310,  
+                @"4\.3\.1\.0\\FSharp\.Core\.dll</HintPath>", 
+                "v4.5",
+                []
+            )
+
+        
+    [<Test>]
+    member public this.``ReferenceResolution.Bug4423.NonFxAssembly.NetTab``() =
+        this.ReferenceResolutionHelper(AddReferenceDialogTab.DotNetTab, 
+                                       Path.Combine(Net20AssemExPathOnThisMachine(), "EnvDTE80.dll"),
+                               (* TODO, no NoPIA support yet, so *)
+                                       @"<Reference Include=""EnvDTE80, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"" />")
+                               (* instead of below
+                                       // TODO the intent here is to match whatever C# does; below is a snapshot from July 7, 2009
+                                       @"<Reference Include=""EnvDTE80, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"">"
+                                     + @"\s*<EmbedInteropTypes>True</EmbedInteropTypes>"
+                                     + @"\s*</Reference>")
+                               *)
+
+    [<Test>]
+    member public this.``ReferenceResolution.Bug4423.NonFxAssembly.BrowseTab.SameVersion``() =
+        let envDte80RefAssemPath = Path.Combine(Net20AssemExPathOnThisMachine(), "EnvDTE80.dll")
+        let dirName = Path.GetTempPath()
+        let copy = Path.Combine(dirName, "EnvDTE80.dll")
+        try
+            File.Copy(envDte80RefAssemPath, copy, true)
+            this.ReferenceResolutionHelper(AddReferenceDialogTab.BrowseTab, 
+                                           copy,
+                                   (*
+                                   For other cases, we mimic C#, but C# has a bug in this case.  Correct result is
+                                   *)
+                                           @"<Reference Include=""EnvDTE80"">"
+                                         // TODO no NoPIA support yet: + @"\s*<EmbedInteropTypes>True</EmbedInteropTypes>"
+                                         + @"\s*<HintPath>\.\.\\EnvDTE80.dll</HintPath>"
+                                         + @"\s*</Reference>")
+                                   (* whereas C# has this: 
+                                           // TODO the intent here is to match whatever C# does; below is a snapshot from July 7, 2009
+                                           @"<Reference Include=""EnvDTE80, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"">"
+                                         + @"\s*<SpecificVersion>False</SpecificVersion>"
+                                         + @"\s*<EmbedInteropTypes>True</EmbedInteropTypes>"
+                                         + (sprintf @"\s*<HintPath>%s</HintPath>" (Regex.Escape copy))
+                                         + @"\s*</Reference>")
+                                   *)
+        finally
+            File.Delete(copy)
+
+    [<Test>]
+    member public this.``ReferenceResolution.Bug650591.AutomationReference.Add.FullPath``() = 
+        let invoker = 
+            {
+                new Microsoft.Internal.VisualStudio.Shell.Interop.IVsInvokerPrivate with
+                    member this.Invoke(invokable) = invokable.Invoke()
+            }
+        let log = 
+            {
+                new Microsoft.VisualStudio.Shell.Interop.IVsActivityLog with
+                    member this.LogEntry(_, _, _) = VSConstants.S_OK
+                    member this.LogEntryGuid(_, _, _, _) = VSConstants.S_OK
+                    member this.LogEntryGuidHr(_, _, _, _, _) = VSConstants.S_OK
+                    member this.LogEntryGuidHrPath(_, _, _, _, _, _) = VSConstants.S_OK
+                    member this.LogEntryGuidPath(_, _, _, _, _) = VSConstants.S_OK
+                    member this.LogEntryHr(_, _, _, _) = VSConstants.S_OK
+                    member this.LogEntryHrPath(_, _, _, _, _) = VSConstants.S_OK
+                    member this.LogEntryPath(_, _, _, _) = VSConstants.S_OK
+            }
+        let mocks = 
+            [
+                typeof<Microsoft.Internal.VisualStudio.Shell.Interop.SVsUIThreadInvokerPrivate>.GUID, box invoker
+                typeof<Microsoft.VisualStudio.Shell.Interop.SVsActivityLog>.GUID, box log
+            ] |> dict
+        let mockProvider = 
+            {
+                new Microsoft.VisualStudio.OLE.Interop.IServiceProvider with
+                    member this.QueryService(guidService, riid, punk) =
+                        match mocks.TryGetValue guidService with
+                        | true, v -> 
+                            punk <- System.Runtime.InteropServices.Marshal.GetIUnknownForObject(v)
+                            VSConstants.S_OK
+                        | _ ->
+                            punk <- IntPtr.Zero
+                            VSConstants.E_NOINTERFACE
+            }
+
+        let _ = Microsoft.VisualStudio.Shell.ServiceProvider.CreateFromSetSite(mockProvider)
+        let envDte80RefAssemPath = Path.Combine(Net20AssemExPathOnThisMachine(), "EnvDTE80.dll")
+        let dirName = Path.GetTempPath()
+        let copy = Path.Combine(dirName, "EnvDTE80.dll")
+        try
+            File.Copy(envDte80RefAssemPath, copy, true)
+            this.MakeProjectAndDo
+                (
+                    ["DoesNotMatter.fs"], 
+                    [], 
+                    "",
+                    fun proj -> 
+                        let refContainer = GetReferenceContainerNode(proj)
+                        let automationRefs = refContainer.Object :?> Automation.OAReferences
+                        automationRefs.Add(copy) |> ignore
+                        SaveProject(proj)
+                        let fsprojFileText = File.ReadAllText(proj.FileName)
+                        printfn "%s" fsprojFileText
+                        let expectedFsProj = 
+                            @"<Reference Include=""EnvDTE80"">"
+                            + @"\s*<HintPath>\.\.\\EnvDTE80.dll</HintPath>"
+                            + @"\s*</Reference>"
+                        TheTests.HelpfulAssertMatches '<' expectedFsProj fsprojFileText
+                )
+        finally
+            File.Delete(copy)
+
+    /// Create a dummy project named 'Test', build it, and then call k with the full path to the resulting exe
+    member public this.CreateDummyTestProjectBuildItAndDo(k : string -> unit) =
+        this.MakeProjectAndDo(["foo.fs"], [], "", (fun project ->
+        // Let's create a run-of-the-mill project just to have a spare assembly around
+        let fooPath = Path.Combine(project.ProjectFolder, "foo.fs")
+        File.AppendAllText(fooPath, "namespace Foo\nmodule Bar =\n  let x = 42")
+        let buildResult = project.Build("Build")
+        Assert.IsTrue buildResult.IsSuccessful
+        let exe = Path.Combine(project.ProjectFolder, "bin\\Debug\\Test.exe")
+        k exe))
+
+    [<Test>]
+    member public this.``ReferenceResolution.Bug4423.NonFxAssembly.BrowseTab.RelativeHintPath.InsideProjectDir``() =
+        // Let's create a run-of-the-mill project just to have a spare assembly around
+        this.CreateDummyTestProjectBuildItAndDo(fun exe ->
+            Assert.IsTrue(File.Exists exe, "failed to build exe")
+            // Now let's create an assembly reference to it and ensure we get expected relative HintPath
+            let expectedFsprojRegex = @"<Reference Include=""Test"">"
+                                         + @"\s*<HintPath>Test.exe</HintPath>"  // in this directory
+                                         + @"\s*</Reference>"
+            this.MakeProjectAndDo(["bar.fs"], [], "", null, (fun project ->
+                let exeCopy = Path.Combine(project.ProjectFolder, "Test.exe")
+                File.Copy(exe, exeCopy, true)                
+                Assert.IsTrue(File.Exists exeCopy, "failed to build exe")
+                let selectorData = new VSCOMPONENTSELECTORDATA(``type`` = VSCOMPONENTTYPE.VSCOMPONENTTYPE_File, bstrFile = exeCopy)
+                let refContainer = GetReferenceContainerNode(project)
+                refContainer.AddReferenceFromSelectorData(selectorData) |> Assert.IsNotNull
+                SaveProject(project)
+                let fsprojFileText = File.ReadAllText(project.FileName)
+                printfn "%s" fsprojFileText
+                TheTests.HelpfulAssertMatches '<' expectedFsprojRegex fsprojFileText
+                // Finally, ensure that the reference works as expected
+                project.Reload()
+                let assemRef = TheTests.FindNodeWithCaption(project, "Test") :?> AssemblyReferenceNode
+                Assert.IsTrue(assemRef.CanShowDefaultIcon(), "the reference could not be resolved")  
+                // Use the referenced DLL as a double-check
+                let barPath = Path.Combine(project.ProjectFolder, "bar.fs")
+                File.AppendAllText(barPath, "printfn \"%d\" Foo.Bar.x")  // code that requires the referenced assembly to successfully compile
+                let buildResult = project.Build("Build")
+                Assert.IsTrue buildResult.IsSuccessful
+                ))
+        )
+        
+    [<Test>]
+    member public this.``ReferenceResolution.Bug4423.NonFxAssembly.BrowseTab.RelativeHintPath.OutsideProjectDir``() =
+        this.MakeProjectAndDo(["foo.fs"], [], "", (fun project ->
+            // Let's create a run-of-the-mill 
+            let fooPath = Path.Combine(project.ProjectFolder, "foo.fs")
+            File.AppendAllText(fooPath, "namespace Foo\nmodule Bar =\n  let x = 42")
+            let buildResult = project.Build("Build")
+            Assert.IsTrue buildResult.IsSuccessful
+            let exe = Path.Combine(project.ProjectFolder, "bin\\Debug\\Test.exe")
+            Assert.IsTrue(File.Exists exe, "failed to build exe")
+            // Now let's create an assembly reference to it and ensure we get expected relative HintPath
+            let expectedFsprojRegex = @"<Reference Include=""Test"">"
+                                         + @"\s*<HintPath>\.\.\\.*?</HintPath>"  // the point is, some path start with "..\", since both projects are rooted somewhere in the temp directory (where unit tests create them)
+                                         + @"\s*</Reference>"
+            this.MakeProjectAndDo(["bar.fs"], [], "", null, (fun project ->
+                let selectorData = new VSCOMPONENTSELECTORDATA(``type`` = VSCOMPONENTTYPE.VSCOMPONENTTYPE_File, bstrFile = exe)
+                let refContainer = GetReferenceContainerNode(project)
+                refContainer.AddReferenceFromSelectorData(selectorData) |> Assert.IsNotNull
+                SaveProject(project)
+                let fsprojFileText = File.ReadAllText(project.FileName)
+                printfn "%s" fsprojFileText
+                TheTests.HelpfulAssertMatches '<' expectedFsprojRegex fsprojFileText
+                // Finally, ensure that the reference works as expected
+                project.Reload()
+                let assemRef = TheTests.FindNodeWithCaption(project, "Test") :?> AssemblyReferenceNode
+                Assert.IsTrue(assemRef.CanShowDefaultIcon(), "the reference could not be resolved")  
+                // Use the referenced DLL as a double-check
+                let barPath = Path.Combine(project.ProjectFolder, "bar.fs")
+                File.AppendAllText(barPath, "printfn \"%d\" Foo.Bar.x")  // code that requires the referenced assembly to successfully compile
+                let buildResult = project.Build("Build")
+                Assert.IsTrue buildResult.IsSuccessful
+                ))
+        ))
+
+    [<Test>]
+    member public this.``ReferenceResolution.Bug4423.NotAValidDll.BrowseTab``() =
+        let dirName = Path.GetTempPath()
+        let dll = Path.Combine(dirName, "Foo.dll")
+        File.AppendAllText(dll, "This is not actually a valid dll")
+        try
+            this.MakeProjectAndDo(["doesNotMatter.fs"], [], "", "v3.5", (fun project ->
+                let selectorData = new VSCOMPONENTSELECTORDATA(``type`` = VSCOMPONENTTYPE.VSCOMPONENTTYPE_File, bstrFile = dll)
+                let refContainer = GetReferenceContainerNode(project)
+                try
+                    refContainer.AddReferenceFromSelectorData(selectorData) |> Assert.IsNotNull
+                    Assert.Fail("this should not have succeeded")
+                with e ->
+                    AssertContains e.Message "could not be added. Please make sure that the file is accessible, and that it is a valid assembly or COM component."
+            ))
+        finally
+            File.Delete(dll)
+
+    [<Test>]
+    member public this.``PathReferences.Existing`` () =
+        DoWithTempFile "Test.fsproj"(fun projFile ->
+            let dirName = Path.GetDirectoryName(projFile)
+            let libDirName = Directory.CreateDirectory(Path.Combine(dirName, "lib")).FullName
+            let codeBase = (new Uri(Assembly.GetExecutingAssembly().CodeBase)).LocalPath |> Path.GetDirectoryName
+            let refLibPath = Path.Combine(libDirName, "nunit.core.dll")
+            File.Copy(Path.Combine(codeBase, "nunit.core.dll"), refLibPath)
+            File.AppendAllText(projFile, TheTests.SimpleFsprojText([], [refLibPath], ""))
+            use project = TheTests.CreateProject(projFile) 
+            let l = new List<AssemblyReferenceNode>()
+            project.FindNodesOfType(l)
+            AssertEqual 1 l.Count
+            AssertEqual refLibPath l.[0].Url
+            AssertEqual refLibPath l.[0].Caption  // when Include is a filename, entirety is caption
+            Assert.IsNotNull(l.[0].ResolvedAssembly)
+            let refContainer =
+                let l = new List<ReferenceContainerNode>()
+                project.FindNodesOfType(l)
+                l.[0]
+            let mscorlibPath = (new Uri("".GetType().Assembly.CodeBase)).LocalPath
+            let selectorData = new VSCOMPONENTSELECTORDATA(``type`` = VSCOMPONENTTYPE.VSCOMPONENTTYPE_ComPlus, bstrFile = mscorlibPath)
+            refContainer.AddReferenceFromSelectorData(selectorData) |> Assert.IsNotNull
+            let l = new List<AssemblyReferenceNode>()
+            project.FindNodesOfType(l)
+            AssertEqual 2 l.Count
+            AssertEqual refLibPath l.[0].Url
+            AssertEqual refLibPath l.[0].Caption
+            AssertEqual "mscorlib" l.[1].Caption
+        )
+
+    [<Test>]
+    member public this.``PathReferences.Existing.Captions`` () =
+        DoWithTempFile "Test.fsproj"(fun projFile ->
+            File.AppendAllText(projFile, TheTests.FsprojTextWithProjectReferences(
+                [], // <Compile>
+                ["$(LetterS)ystem.dll"; "System.Net.dll"], // <Reference>
+                [], // <ProjectReference>
+                "<PropertyGroup><LetterS>S</LetterS></PropertyGroup>"))  // other stuff
+            use project = TheTests.CreateProject(projFile) 
+            let l = new List<AssemblyReferenceNode>()
+            project.FindNodesOfType(l)
+            AssertEqual 2 l.Count
+            AssertEqual "System.dll" l.[0].Caption
+            Assert.IsNotNull(l.[0].ResolvedAssembly)
+            AssertEqual "System.Net.dll" l.[1].Caption
+            Assert.IsNotNull(l.[1].ResolvedAssembly)
+        )
+        
+    [<Test>]
+    member public this.``PathReferences.NonExistent`` () =
+        DoWithTempFile "Test.fsproj"(fun projFile ->
+            let refLibPath = @"c:\foo\baz\blahblah.dll"
+            File.AppendAllText(projFile, TheTests.SimpleFsprojText([], [refLibPath], ""))
+            use project = TheTests.CreateProject(projFile) 
+            let l = new List<AssemblyReferenceNode>()
+            project.FindNodesOfType(l)
+            AssertEqual 1 l.Count
+            AssertEqual refLibPath l.[0].Caption
+            Assert.IsNull(l.[0].ResolvedAssembly)
+        )
+
+        
+    [<Test>]
+    member public this.``FsprojPreferencePage.ProjSupportsPrefReadWrite``() =
+        let testProp = "AssemblyName"
+        let compileItem = [@"foo.fs"]
+        
+        DoWithTempFile "Test.fsproj" (fun projFile ->
+            File.AppendAllText(projFile, TheTests.SimpleFsprojText(compileItem, [], "")) 
+            use project = TheTests.CreateProject(projFile) 
+            // Read a known property from the project node - AssemblyName
+            let propertyVal = project.GetProjectProperty(testProp, false)
+            // Set the project property to something different (is currently "MyAssembly")
+            let newPropVal = "Foo_PROPVAL_Foo" // hopefully unique?
+            project.SetProjectProperty(testProp, newPropVal)
+            // get the (hopefully) modified property name
+            let propertyVal' = project.GetProjectProperty(testProp, false)
+            let newProjFileName = (Path.GetDirectoryName projFile) + "\\" + "fooProj.fsproj"
+            
+            printfn "%s before modification: %s" testProp propertyVal 
+            printfn "%s after modification:  %s" testProp propertyVal' 
+            
+            // Assert that the value has changed
+            AssertNotEqual propertyVal propertyVal'
+            // Assert that the new value is what we expect it to be 
+            AssertEqual newPropVal propertyVal'
+            
+            // Save as a new project file
+            project.SaveMSBuildProjectFileAs(newProjFileName) ; // cleaned up by parent call to DoWithTempFile
+            
+            // look for the new property inside of the project file
+            let contents = File.ReadAllText(newProjFileName)
+            AssertContains contents newPropVal
+        )
\ No newline at end of file
diff --git a/vsintegration/src/unittests/Tests.ProjectSystem.RoundTrip.fs b/vsintegration/src/unittests/Tests.ProjectSystem.RoundTrip.fs
new file mode 100644
index 0000000..600adeb
--- /dev/null
+++ b/vsintegration/src/unittests/Tests.ProjectSystem.RoundTrip.fs
@@ -0,0 +1,140 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+namespace UnitTests.Tests.ProjectSystem
+
+open System
+open System.IO
+open System.Text.RegularExpressions
+open NUnit.Framework
+open UnitTests.TestLib.Utils.Asserts
+open UnitTests.TestLib.Utils.FilesystemHelpers
+open UnitTests.TestLib.ProjectSystem
+open Microsoft.VisualStudio.FSharp.ProjectSystem
+
+
+[<TestFixture>]
+type RoundTrip() = 
+    inherit TheTests()
+    
+    /////////////////////////////////
+    // project helpers
+    static let SaveProject(project : UnitTestingFSharpProjectNode) =
+        project.Save(null, 1, 0u) |> ignore
+    
+    member this.``FsprojRoundtrip.PositiveTest``(origItems : MSBuildItems, expectedItems : MSBuildItems) =
+        // test that opening with origItems and saving yields expectedItems
+        this.MakeProjectAndDoWithProjectFile([], [], origItems.ToString(), (fun project fileName ->
+            SaveProject(project)
+            let fsprojFileText = File.ReadAllText(fileName)
+            printfn "%s" fsprojFileText
+            let regexStr = expectedItems.AsRegexString()
+            TheTests.HelpfulAssertMatches '<' regexStr fsprojFileText
+            if Regex.IsMatch(fsprojFileText, "<ItemGroup>\s*</ItemGroup>") then
+                Assert.Fail("did not remove empty ItemGroups")
+        ))
+        // test idempotentcy (opening with previous-saved results causes no change)
+        this.MakeProjectAndDoWithProjectFile([], [], expectedItems.ToString(), (fun project fileName ->
+            SaveProject(project)
+            let fsprojFileText = File.ReadAllText(fileName)
+            printfn "%s" fsprojFileText
+            let regexStr = expectedItems.AsRegexString()
+            TheTests.HelpfulAssertMatches '<' regexStr fsprojFileText
+            if Regex.IsMatch(fsprojFileText, "<ItemGroup>\s*</ItemGroup>") then
+                Assert.Fail("did not remove empty ItemGroups")
+        ))
+
+    [<Test>]
+    member public this.``FsprojRoundTrip.Basic.NonemptyFoldersRemoved.Case1``() =
+        this.``FsprojRoundtrip.PositiveTest``(
+            MSBuildItems [CompileItem @"bar.fs"
+                          FolderItem @"Folder\"
+                          CompileItem @"Folder\foo.fs"],
+            MSBuildItems [CompileItem @"bar.fs"
+                          CompileItem @"Folder\foo.fs"])
+
+    [<Test>]
+    member public this.``FsprojRoundTrip.Basic.NonemptyFoldersRemoved.Case2``() =
+        this.``FsprojRoundtrip.PositiveTest``(
+            MSBuildItems [CompileItem @"bar.fs"
+                          FolderItem @"A\"
+                          FolderItem @"A\B\"
+                          FolderItem @"A\B\C\"
+                          CompileItem @"A\B\C\foo.fs"
+                          CompileItem @"A\qux.fs"],
+            MSBuildItems [CompileItem @"bar.fs"
+                          CompileItem @"A\B\C\foo.fs"
+                          CompileItem @"A\qux.fs"])
+
+    [<Test>]
+    member public this.``FsprojRoundTrip.ComplexButLegalCase``() =
+        let items = MSBuildItems [CompileItem @"A\B\foo.fs"
+                                  CompileItem @"A\bar.fs"
+                                  CompileItem @"A\C\D\qux.fs"
+                                  CompileItem @"A\xyz.fs"
+                                  CompileItem @"ddd.fs"
+                                  CompileItem @"E\eee.fs"
+                                  ]
+        this.``FsprojRoundtrip.PositiveTest``(items, items)
+
+    [<Test>]
+    member public this.``FsprojRoundTrip.EmptyFoldersArePreservedWhenRestIsIdempotent``() =
+        let items = MSBuildItems [CompileItem @"bar.fs"
+                                  FolderItem @"A\Empty1\"
+                                  CompileItem @"A\B\C\foo.fs"
+                                  FolderItem @"A\B\Empty2\"
+                                  CompileItem @"A\qux.fs"]
+        this.``FsprojRoundtrip.PositiveTest``(items, items)
+
+    [<Test>]
+    member public this.``FsprojRoundTrip.EmptyFoldersArePreservedWhenRestIsLegalButNotIdempotent``() =
+        let origItems = [CompileItem @"bar.fs"
+                         FolderItem @"A\Empty1\"        
+                         FolderItem @"A\B\"              // will get removed
+                         CompileItem @"A\B\C\foo.fs"
+                         FolderItem @"A\B\Empty2\"
+                         CompileItem @"A\qux.fs"]
+        let expectedItems = [CompileItem @"bar.fs"
+                             FolderItem @"A\Empty1\"
+                             CompileItem @"A\B\C\foo.fs"
+                             FolderItem @"A\B\Empty2\"
+                             CompileItem @"A\qux.fs"]
+        this.``FsprojRoundtrip.PositiveTest``(MSBuildItems origItems, MSBuildItems expectedItems)
+
+    member this.``Fsproj.NegativeTest``(items : MSBuildItems) =
+        DoWithTempFile "Test.fsproj" (fun file ->
+            File.AppendAllText(file, TheTests.SimpleFsprojText([], [], items.ToString()))
+            let ex = new System.Exception()
+            try
+                use project = TheTests.CreateProject(file)
+                let mutable node = project.FirstChild
+                TheTests.PrintHierarchy(node)
+                raise ex
+            with
+            | e when obj.ReferenceEquals(e,ex) -> Assert.Fail("did not expect to succeed creating project")
+            | :? InvalidOperationException as e when e.ToString().Contains("rendered") ->
+                printfn "As expected, failed to create project.  Reason: %s" (e.Message)
+            | e -> Assert.Fail("failed to create project, but for wrong reason")
+            ()
+        )
+
+    [<Test>]
+    member public this.``FsprojRoundTrip.Basic.Invalid.Case1``() =
+        let items = MSBuildItems [CompileItem @"A\B\C\foo.fs"
+                                  CompileItem @"B\bar.fs"
+                                  CompileItem @"A\B\D\qux.fs"]  // would cause A to be rendered twice
+        this.``Fsproj.NegativeTest`` items
+
+    [<Test>]
+    member public this.``FsprojRoundTrip.Basic.Invalid.Case2``() =
+        let items = MSBuildItems [CompileItem @"A\foo.fs"
+                                  CompileItem @"bar.fs"
+                                  CompileItem @"A\qux.fs"]  // would cause A to be rendered twice
+        this.``Fsproj.NegativeTest`` items
+
+    // REVIEW NYI: [<Test>]
+    member public this.``FsprojRoundTrip.Basic.Invalid.Case3``() =
+        let items = MSBuildItems [CompileItem @"A\foo.fs"
+                                  FolderItem @"A\"           // <Folder> must be before anything below it
+                                  CompileItem @"bar.fs"]
+        this.``Fsproj.NegativeTest`` items
+        
diff --git a/vsintegration/src/unittests/Tests.TaskReporter.fs b/vsintegration/src/unittests/Tests.TaskReporter.fs
new file mode 100644
index 0000000..ab5e80f
--- /dev/null
+++ b/vsintegration/src/unittests/Tests.TaskReporter.fs
@@ -0,0 +1,369 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+namespace UnitTests.Tests
+
+open NUnit.Framework
+open System
+open System.IO
+open System.Diagnostics
+open Microsoft.FSharp.Build
+open Microsoft.Build.BuildEngine
+open Microsoft.Build.Framework
+open Microsoft.Build.Utilities
+open UnitTests.TestLib.Utils
+open UnitTests.TestLib.Utils.FilesystemHelpers
+open Microsoft.VisualStudio.Shell
+
+open Salsa.Salsa
+open Salsa.VsMocks
+
+type TextSpan = Microsoft.VisualStudio.TextManager.Interop.TextSpan
+type DocumentTask = Microsoft.VisualStudio.FSharp.LanguageService.DocumentTask
+
+[<TestFixture>]
+type TaskReporter() = 
+    static let err(line) : 'a = 
+        printfn "err() called on line %s with %s" line System.Environment.StackTrace 
+        failwith "not implemented"
+
+    let mockOleComponentManager = 
+        { new Microsoft.VisualStudio.OLE.Interop.IOleComponentManager with
+            member x.FContinueIdle() = 1
+            member x.FCreateSubComponentManager(piunkOuter, piunkServProv, riid, ppvObj) = err(__LINE__)
+            member x.FGetActiveComponent(dwgac, ppic, pcrinfo, dwReserved) = err(__LINE__)
+            member x.FGetParentComponentManager(ppicm) = err(__LINE__)
+            member x.FInState(uStateID, pvoid) = err(__LINE__)
+            member x.FOnComponentActivate(dwComponentID) = err(__LINE__)
+            member x.FOnComponentExitState(dwComponentID, uStateID, uContext, cpicmExclude, rgpicmExclude) = err(__LINE__)
+            member x.FPushMessageLoop(dwComponentID, uReason, pvLoopData) = err(__LINE__)
+            member x.FRegisterComponent(piComponent, pcrinfo, pdwComponentID) = err(__LINE__)
+            member x.FReserved1(dwReserved, message, wParam, lParam) = err(__LINE__)
+            member x.FRevokeComponent(dwComponentID) = err(__LINE__)
+            member x.FSetTrackingComponent(dwComponentID, fTrack) = err(__LINE__)
+            member x.FUpdateComponentRegistration(dwComponentID, pcrinfo) = err(__LINE__)
+            member x.OnComponentEnterState(dwComponentID, uStateID, uContext, cpicmExclude, rgpicmExclude, dwReserved) = err(__LINE__)
+            member x.QueryService(guidService, iid, ppvObj) = err(__LINE__) 
+            }
+
+
+    (* Asserts ----------------------------------------------------------------------------- *)
+    let AssertEqual expected actual =
+        if expected<>actual then 
+            let message = sprintf "Expected\n%A\nbut got\n%A" expected actual
+            printfn "%s" message
+            Assert.Fail(message)
+            
+    let AssertNotEqual expected actual =
+        if expected = actual then
+            let message = sprintf "Did not want\n%A\nbut got it anyway" expected
+            printfn "%s" message
+            Assert.Fail(message)
+            
+    let GetNewDocumentTask filePath subcategory span errorMessage taskPriority taskCategory taskErrorCategory =
+        let dt = new Microsoft.VisualStudio.FSharp.LanguageService.DocumentTask(null, 
+                        Salsa.VsMocks.Vs.MakeTextLines(), 
+                        Microsoft.VisualStudio.TextManager.Interop.MARKERTYPE.MARKER_CODESENSE_ERROR,
+                        span,
+                        filePath,
+                        subcategory)
+        dt.Text <- errorMessage ;
+        dt.Priority <- taskPriority ;
+        dt.Category <- taskCategory ;
+        dt.ErrorCategory <- taskErrorCategory ;
+        dt
+        
+    let CreateTaskListProvider() =
+        let tasks : Task array ref = ref [||]
+        
+        { new Microsoft.VisualStudio.FSharp.LanguageService.ITaskListProvider with
+            member tl.Count() = (!tasks).Length
+            member tl.GetTask i = (!tasks).[i]
+            member tl.Add t = tasks := Array.append !tasks [| t |]
+            member tl.SuspendRefresh() = ()
+            member tl.ResumeRefresh() = ()
+            member tl.Clear() = tasks := [||]
+            member tl.Refresh() = ()
+        }
+        
+    let CreateTaskReporter() =
+        UIStuff.SetupSynchronizationContext()
+        let taskReporter = new Microsoft.VisualStudio.FSharp.LanguageService.TaskReporter("unit test (taskreporter.unittests.fs)")
+        taskReporter.TaskListProvider <- CreateTaskListProvider() ;
+        taskReporter
+
+// One File Tests
+    // For the next two, add tasks to the task list more than once to ensure that
+    // hashing is occuring correctly   
+    [<Test>]
+    member public this.``ErrorList.LanguageServiceErrorsProperlyCoalesced``() =  
+        use taskReporter = CreateTaskReporter()
+        let mutable span = new TextSpan(iStartLine = 1, iEndLine = 1, iStartIndex = 1, iEndIndex = 2)
+        let documentTask = GetNewDocumentTask @"c:\foo.fs" "typecheck" span "foo error!" TaskPriority.High TaskCategory.BuildCompile TaskErrorCategory.Error
+        
+        // add a language service error
+        taskReporter.AddTask(documentTask) |> ignore
+        
+        // add the error to the language service again
+        taskReporter.AddTask(documentTask) |> ignore
+        
+        taskReporter.OutputTaskList()
+        
+        taskReporter.DoIdle(mockOleComponentManager) |> ignore
+        AssertEqual (taskReporter.TaskListProvider.Count()) 1
+        ()
+        
+        
+        
+    [<Test>]
+    member public this.``ErrorList.ProjectSystemErrorsProperlyCoalesced``() =  
+        use taskReporter = CreateTaskReporter()
+        let mutable span = new TextSpan(iStartLine = 1, iEndLine = 1, iStartIndex = 1, iEndIndex = 2)
+        let documentTask = GetNewDocumentTask @"c:\foo.fs" "typecheck" span "foo error!" TaskPriority.High TaskCategory.BuildCompile TaskErrorCategory.Error
+        
+        // add a project system error
+        taskReporter.AddTask(documentTask) |> ignore
+        
+        // add the error to the project system again
+        taskReporter.AddTask(documentTask) |> ignore
+        
+        taskReporter.OutputTaskList()
+        
+        taskReporter.DoIdle(mockOleComponentManager) |> ignore
+        AssertEqual (taskReporter.TaskListProvider.Count()) 1
+        
+        ()
+        
+    /// Test for multiple identical errors being properly coalesced in the error list (bug 2151)
+    [<Test>]
+    member public this.``ErrorList.ErrorsProperlyCoalesced``() =  
+        use taskReporter = CreateTaskReporter()
+        let mutable span = new TextSpan(iStartLine = 1, iEndLine = 1, iStartIndex = 1, iEndIndex = 2)
+        let documentTask = GetNewDocumentTask @"c:\foo.fs" "typecheck" span "foo error!" TaskPriority.High TaskCategory.BuildCompile TaskErrorCategory.Error
+        
+        // add a language service error
+        taskReporter.AddTask(documentTask) |> ignore
+        
+        // add a project system error
+        taskReporter.AddTask(documentTask) |> ignore
+        
+        taskReporter.OutputTaskList()
+        
+        taskReporter.DoIdle(mockOleComponentManager) |> ignore
+        AssertEqual (taskReporter.TaskListProvider.Count()) 1
+        ()
+    
+    // modify the span, and check to see if we have two tasks now instead of one    
+    [<Test>]
+    member public this.``ErrorList.ProjectSystemErrorsProperlyCoalesced2``() =  
+        use taskReporter = CreateTaskReporter()
+        let mutable span = new TextSpan(iStartLine = 1, iEndLine = 1, iStartIndex = 1, iEndIndex = 2)
+        let documentTask1 = GetNewDocumentTask @"c:\foo.fs" "typecheck" span "foo error!" TaskPriority.High TaskCategory.BuildCompile TaskErrorCategory.Error
+        
+        span.iStartLine <- 2;
+        span.iEndLine <- 2;
+        
+        let documentTask2 = GetNewDocumentTask @"c:\foo.fs" "typecheck" span "foo error!" TaskPriority.High TaskCategory.BuildCompile TaskErrorCategory.Error
+        
+        // add the errors
+        taskReporter.AddTask(documentTask1) |> ignore
+        taskReporter.AddTask(documentTask2) |> ignore
+        
+        taskReporter.OutputTaskList()
+        
+        taskReporter.DoIdle(mockOleComponentManager) |> ignore
+        AssertEqual (taskReporter.TaskListProvider.Count()) 2
+        ()
+        
+    /// Ensure that text line markers are only created when a task is output to the the task list
+    [<Test>]
+    member public this.``ErrorList.TextLineMarkersCreatedOnce``() =  
+        use taskReporter = CreateTaskReporter()
+        let mutable span = new TextSpan(iStartLine = 1, iEndLine = 1, iStartIndex = 1, iEndIndex = 2)
+        let documentTask = GetNewDocumentTask @"c:\foo.fs" "typecheck" span "foo error!" TaskPriority.High TaskCategory.BuildCompile TaskErrorCategory.Error
+        let documentTask2 = GetNewDocumentTask @"c:\foo.fs" "typecheck"  span "foo error!" TaskPriority.High TaskCategory.BuildCompile TaskErrorCategory.Error
+        
+        // ensure that the tasks don't have a text line marker yet
+        AssertEqual documentTask.TextLineMarker null
+        AssertEqual documentTask2.TextLineMarker null
+        
+        // add a language service error
+        taskReporter.AddTask(documentTask) |> ignore
+        
+        // add a project system error
+        taskReporter.AddTask(documentTask2) |> ignore
+        
+        taskReporter.OutputTaskList()
+        
+        taskReporter.DoIdle(mockOleComponentManager) |> ignore
+        AssertEqual (taskReporter.TaskListProvider.Count()) 1
+        
+        // ensure that the task now has a text line marker
+        AssertNotEqual documentTask.TextLineMarker null
+        
+        // now, make sure that the rejected task does not have a text line marker
+        AssertEqual documentTask2.TextLineMarker null
+        
+        ()                    
+ 
+ // Two file tests
+ 
+ 
+ 
+ 
+    // both files open
+    // errors in each file, build - no duplicates  
+    [<Test>]
+    member public this.``ErrorList.TwoFilesBothOpen``() =  
+        use taskReporter = CreateTaskReporter()
+        let mutable span = new TextSpan(iStartLine = 1, iEndLine = 1, iStartIndex = 1, iEndIndex = 2)
+        let documentTask1 = GetNewDocumentTask @"c:\foo.fs" "typecheck" span "foo error!" TaskPriority.High TaskCategory.BuildCompile TaskErrorCategory.Error
+        let documentTask2 = GetNewDocumentTask @"c:\bar.fs" "typecheck" span "foo error!" TaskPriority.High TaskCategory.BuildCompile TaskErrorCategory.Error
+        
+        // add the errors
+        taskReporter.AddTask(documentTask1) |> ignore
+        taskReporter.AddTask(documentTask2) |> ignore
+        
+        taskReporter.OutputTaskList()
+        
+        // ensure that we now have two distinct tasks in the task list
+        taskReporter.DoIdle(mockOleComponentManager) |> ignore
+        AssertEqual (taskReporter.TaskListProvider.Count()) 2
+        
+        // are the tasks ordered correctly?
+        let task1 = taskReporter.TaskListProvider.GetTask(0) :?> DocumentTask
+        let task2 = taskReporter.TaskListProvider.GetTask(1) :?> DocumentTask
+        AssertEqual documentTask1 task2  // reordered based on filename
+        AssertEqual documentTask2 task1      
+        ()           
+ 
+     // file open, one file closed
+     // - error in closed file
+    [<Test>]
+    member public this.``ErrorList.TwoFilesOneOpenErrorInOpen``() =  
+        use taskReporter = CreateTaskReporter()
+        let mutable span = new TextSpan(iStartLine = 1, iEndLine = 1, iStartIndex = 1, iEndIndex = 2)
+        let documentTask1 = GetNewDocumentTask @"c:\foo.fs" "typecheck" span "foo error!" TaskPriority.High TaskCategory.BuildCompile TaskErrorCategory.Error
+        let documentTask2 = GetNewDocumentTask @"c:\bar.fs" "typecheck" span "bar error!" TaskPriority.High TaskCategory.BuildCompile TaskErrorCategory.Error
+        let documentTask3 = GetNewDocumentTask @"c:\foo.fs" "typecheck" span "foo error!" TaskPriority.High TaskCategory.BuildCompile TaskErrorCategory.Error        
+        
+        // add the background task ("foo.fs" is opened)
+        taskReporter.AddTask(documentTask1) |> ignore
+        
+        // now simulate a build - add task 2, and task 3 (which is the same as task 1)
+        taskReporter.AddTask(documentTask2) |> ignore
+        taskReporter.AddTask(documentTask3) |> ignore
+        
+        // get "all" tasks - if working correctly - the three tasks will have been coalesced into two (tasks 1 and 3 will be the same)
+        taskReporter.OutputTaskList()
+        
+        taskReporter.DoIdle(mockOleComponentManager) |> ignore
+        // ensure that we now have two distinct tasks in the task list
+        AssertEqual (taskReporter.TaskListProvider.Count()) 2
+        
+        // are the tasks ordered correctly?
+        let task1 = taskReporter.TaskListProvider.GetTask(0) :?> DocumentTask
+        let task2 = taskReporter.TaskListProvider.GetTask(1) :?> DocumentTask
+        AssertEqual documentTask3 task2  // reordered based on filename
+        AssertEqual documentTask2 task1      
+        ()           
+ 
+    // all files open - build, then fix - no errors left
+    [<Test>]
+    member public this.``ErrorList.TwoFilesCorrectError``() =  
+        use taskReporter = CreateTaskReporter()
+        let mutable span = new TextSpan(iStartLine = 1, iEndLine = 1, iStartIndex = 1, iEndIndex = 2)
+        let documentTask1 = GetNewDocumentTask @"c:\foo.fs" "typecheck" span "foo error!" TaskPriority.High TaskCategory.BuildCompile TaskErrorCategory.Error
+        let documentTask2 = GetNewDocumentTask @"c:\bar.fs" "typecheck" span "bar error!" TaskPriority.High TaskCategory.BuildCompile TaskErrorCategory.Error
+        let documentTask3 = GetNewDocumentTask @"c:\foo.fs" "typecheck" span "foo error!" TaskPriority.High TaskCategory.BuildCompile TaskErrorCategory.Error
+        let documentTask4 = GetNewDocumentTask @"c:\bar.fs" "typecheck" span "bar error!" TaskPriority.High TaskCategory.BuildCompile TaskErrorCategory.Error
+        
+        // add the background tasks ("foo.fs" and "bar".fs are opened)
+        taskReporter.AddTask(documentTask1) |> ignore
+        taskReporter.AddTask(documentTask2) |> ignore
+        
+        // now simulate a build - add task 3, and task 4 (which are the same as tasks 1 and 2)
+        taskReporter.AddTask(documentTask3) |> ignore
+        taskReporter.AddTask(documentTask4) |> ignore
+        
+        taskReporter.OutputTaskList()
+        
+        taskReporter.DoIdle(mockOleComponentManager) |> ignore
+        // after the "build", we shouldn't have any build tasks, since they already belong to the LS
+        let backgroundTasks = taskReporter.GetBackgroundTasks();
+        let buildTasks = taskReporter.GetBuildTasks();
+             
+        // ensure that we now have two distinct tasks in the task list
+        AssertEqual (taskReporter.TaskListProvider.Count()) 2
+        AssertEqual (backgroundTasks.GetLength(0)) 2
+        AssertEqual (buildTasks.GetLength(0)) 0
+        
+        // are the tasks ordered correctly?
+        let task1 = taskReporter.TaskListProvider.GetTask(0) :?> DocumentTask
+        let task2 = taskReporter.TaskListProvider.GetTask(1) :?> DocumentTask
+        AssertEqual documentTask1 task2  // reordered based on filename
+        AssertEqual documentTask2 task1
+        
+        // simulate a fix by clearing out the c:\foo.fs errors
+        taskReporter.ClearBackgroundTasksForFile(@"c:\foo.fs")
+        taskReporter.OutputTaskList()
+        taskReporter.DoIdle(mockOleComponentManager) |> ignore
+        let task1 = taskReporter.TaskListProvider.GetTask(0) :?> DocumentTask
+        AssertEqual (taskReporter.TaskListProvider.Count()) 1
+        AssertEqual task1 documentTask2       
+        ()  
+        
+        
+    // Make sure a 'typecheck' is treated as a background task
+    [<Test>]
+    member public this.``ErrorList.BackgroundTaskIsClassified``() =  
+        use taskReporter = CreateTaskReporter()
+        let mutable span = new TextSpan(iStartLine = 1, iEndLine = 1, iStartIndex = 1, iEndIndex = 2)
+        let dt = GetNewDocumentTask @"c:\foo.fs" "typecheck" span "foo error!" TaskPriority.High TaskCategory.BuildCompile TaskErrorCategory.Error
+        
+        taskReporter.AddTask(dt) |> ignore
+        
+        taskReporter.OutputTaskList()
+        
+        taskReporter.DoIdle(mockOleComponentManager) |> ignore
+
+        let backgroundTasks = taskReporter.GetBackgroundTasks();
+        let buildTasks = taskReporter.GetBuildTasks();
+             
+        // There should be one error in the list.
+        AssertEqual (taskReporter.TaskListProvider.Count()) 1
+        
+        // It should be a background task.
+        AssertEqual (backgroundTasks.GetLength(0)) 1
+        
+        // There should be no build tasks.
+        AssertEqual (buildTasks.GetLength(0)) 0
+        
+        ()        
+        
+        
+    // Make sure a 'ilxgen' is treated as a build task
+    [<Test>]
+    member public this.``ErrorList.BuildTaskIsClassified``() =  
+        use taskReporter = CreateTaskReporter()
+        let mutable span = new TextSpan(iStartLine = 1, iEndLine = 1, iStartIndex = 1, iEndIndex = 2)
+        let dt = GetNewDocumentTask @"c:\foo.fs" "ilxgen" span "foo error!" TaskPriority.High TaskCategory.BuildCompile TaskErrorCategory.Error
+        
+        taskReporter.AddTask(dt) |> ignore
+        
+        taskReporter.OutputTaskList()
+        
+        taskReporter.DoIdle(mockOleComponentManager) |> ignore
+
+        let backgroundTasks = taskReporter.GetBackgroundTasks();
+        let buildTasks = taskReporter.GetBuildTasks();
+             
+        // There should be one error in the list.
+        AssertEqual (taskReporter.TaskListProvider.Count()) 1
+        
+        // It should be a build task.
+        AssertEqual (buildTasks.GetLength(0)) 1
+        
+        // There should be no background tasks.
+        AssertEqual (backgroundTasks.GetLength(0)) 0
+        
+        ()                
diff --git a/vsintegration/src/unittests/Tests.TypeProvidersImpl.fs b/vsintegration/src/unittests/Tests.TypeProvidersImpl.fs
new file mode 100644
index 0000000..20d4716
--- /dev/null
+++ b/vsintegration/src/unittests/Tests.TypeProvidersImpl.fs
@@ -0,0 +1,374 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+namespace UnitTests.Tests
+
+open System.IO
+open NUnit.Framework
+
+module U = Microsoft.FSharp.Data.TypeProviders.DesignTime.Utilities
+module CF = Microsoft.FSharp.Data.TypeProviders.DesignTime.ConfigFiles
+module Util = Microsoft.FSharp.Data.TypeProviders.Utility.Util
+
+[<TestFixture>]
+type TypeProviderImplTests() = 
+    
+    [<Test>]
+    member public this.``SanitizeFileName``() = 
+        let tests = 
+            [
+                "NorthWind", "Northwind"
+                "1NorthWind", "_1northwind"
+                "north (wind)", "North_wind_"
+                "north wind", "NorthWind"
+                "North(Wind)", "North_wind_"
+                "(northwind)", "_northwind_"
+                "^#$&5wind", "____5wind"
+            ]
+        for (source, expected) in tests do
+            let actual = U.sanitizeDataContextFileName source
+            printfn "source: %s, expected %s, actual %s" source expected actual
+            Assert.AreEqual(expected, actual)
+
+    [<Test>]
+    member public this.``ParseCodegenToolErrors.RecognizeErrorLine``() = 
+        let tests =
+            [
+                // known localization related items 
+                [||], [|"error 7015: Parameter switch 'targetversion' is not valid."|], ["error 7015: Parameter switch 'targetversion' is not valid."]
+                [||], [|"!stsMv!error 7015: !3eCOn!Parameter switch 'L' is not valid. 表c?字㌍!"|], ["!stsMv!error 7015: !3eCOn!Parameter switch 'L' is not valid. 表c?字㌍!"]
+                [||], [|"에러 7015: Parameter switch 'targetversion' is not valid." |], ["에러 7015: Parameter switch 'targetversion' is not valid."]
+                [||], [|"!pM1WE!Error:  表c!!i2yz2!Cannot read .. 表c?!"|], ["!pM1WE!Error:  表c!!i2yz2!Cannot read .. 表c?!"]
+                [||], [|"エラー: . を読み取れません"|], ["エラー: . を読み取れません"]
+                // regular 
+                [||], [|"Error: Cannot obtain Metadata from http://bing.com/" |], ["Error: Cannot obtain Metadata from http://bing.com/"]
+            ]
+
+        for (stdin, stderr, expectedErrs) in tests do
+            try
+                U.formatErr stdin stderr
+                Assert.Fail("Should throw")
+            with
+                | :? System.AggregateException as ae -> 
+                    let actualErrs = ae.InnerExceptions |> Seq.map (fun e -> e.Message) |> set
+                    let expectedErrs = set expectedErrs
+                    printfn "Expected: %A" expectedErrs
+                    printfn "Actual: %A" actualErrs
+                    Assert.IsTrue(actualErrs.Count = expectedErrs.Count)
+                    Assert.IsTrue((actualErrs - expectedErrs).Count = 0)
+                | e -> sprintf "unexpected exception %A" e |> Assert.Fail
+
+    [<Test>]
+    member public this.``ParseCodegenToolErrors.FalsePositives``() = 
+        let stdin = 
+             [|
+                 "Attempting to download metadata from 'http://bing.com/' using WS-Metadata Exchange or DISCO."
+                 "Microsoft (R) Service Model Metadata Tool"
+                 "[Microsoft (R) Windows (R) Communication Foundation, Version 4.0.30319.17360]"
+                 "Copyright (c) Microsoft Corporation.  All rights reserved."
+                 ""
+                 ""
+                 ""
+                 "If you would like more help, type \"svcutil /?\""
+             |]
+        let stderr = 
+             [|
+                 "Error: Cannot obtain Metadata from http://bing.com/ "
+                 ""
+                 "If this is a Windows (R) Communication Foundation service to which you have access, please check that you have enabled metadata publishing at the specified address.  For help enabling metadata publishing, please refer to the MSDN documentation at http://go.microsoft.com/fwlink/?LinkId=65455."
+                 ""
+                 "WS-Metadata Exchange Error"
+                 "    URI: http://bing.com/"
+                 ""
+                 "    Metadata contains a reference that cannot be resolved: 'http://bing.com/'."
+                 ""
+                 "    The content type text/html; charset=utf-8 of the response message does not match the content type of the binding (application/soap+xml; charset=utf-8). If using a custom encoder, be sure that the IsContentTypeSupported method is implemented properly. The first 194 bytes of the response were: '<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\"><html lang=\"en\" xml:lang=\"en\" xmlns=\"http://ww [...]
+                 ""
+                 "HTTP GET Error"
+                 "    URI: http://bing.com/"
+                 ""
+                 "    The HTML document does not contain Web service discovery information."
+                 ""
+             |]
+        try
+            U.formatErr stdin stderr
+            Assert.Fail("Should throw")
+        with
+            | :? System.AggregateException as ae -> 
+                printfn "%A" ae
+                Assert.IsTrue (ae.InnerExceptions.Count = 1, "One exception expected")
+                Assert.IsTrue(ae.InnerExceptions.[0].Message = "Error: Cannot obtain Metadata from http://bing.com/")
+            | e -> sprintf "unexpected exception %A" e |> Assert.Fail
+    
+    [<Test>]
+    member public this.``PathResolutionUtils.MakeAbsolute``() = 
+        use d = Util.TemporaryDirectory()
+        let pru = Microsoft.FSharp.Data.TypeProviders.DesignTime.PathResolutionUtils(d.Path)
+        
+        // NullOrEmpty
+        Assert.AreEqual(null, pru.MakeAbsolute(d.Path, null), "null expected")
+        Assert.AreEqual("", pru.MakeAbsolute(d.Path, ""), "empty string expected")
+
+        // rooted path
+        let subFolder = Path.Combine(d.Path, "Subfolder")
+        Assert.AreEqual(subFolder, pru.MakeAbsolute(d.Path, subFolder), "absolute path should be returned as is")
+
+        // relative path
+        Assert.AreEqual(subFolder, pru.MakeAbsolute(d.Path, "Subfolder"), "relative path should be converted to absolute")
+
+    [<Test>]
+    member public this.``PathResolutionUtils.GetAbsoluteDesignTimeDirectory``() = 
+        use d = Util.TemporaryDirectory()
+        let pru = Microsoft.FSharp.Data.TypeProviders.DesignTime.PathResolutionUtils(d.Path)
+        
+        // absolute path
+        Assert.AreEqual(d.Path, pru.GetAbsoluteDesignTimeDirectory(d.Path), "absolute path should be returned as is")
+        
+        // relative path
+        let name = "Subfolder"
+        let expected = Path.Combine(d.Path, name)
+        Assert.AreEqual(expected, pru.GetAbsoluteDesignTimeDirectory(name), "relative path should be converted to absolute")
+
+    [<Test>]
+    member public this.``PathResolutionUtils.GetConfigFileWatchSpec.ResolvedPathsInSpecs``() = 
+        let (++) a b = Path.Combine(a, b)
+        (
+            use d = Util.TemporaryDirectory()
+            let pru = Microsoft.FSharp.Data.TypeProviders.DesignTime.PathResolutionUtils(d.Path)
+        
+            // no connection string name set
+            pru.GetConfigFileWatchSpec(null, null, null) 
+            |> List.length
+            |> fun l -> Assert.AreEqual(0, l, "Connection string name not set => not watch specs expected")
+        )
+
+        let check caption resFolder configFile f = 
+            printfn "Running %s" caption
+            use d = Util.TemporaryDirectory()
+            let pru = Microsoft.FSharp.Data.TypeProviders.DesignTime.PathResolutionUtils(d.Path)
+            match pru.GetConfigFileWatchSpec(resFolder, configFile, "Name") with
+            | [r] -> f (d, r)
+            | x -> sprintf "%s - unexpected result %A" caption x |> Assert.Fail
+            printfn "Finished %s" caption
+            
+
+        // NOT FOUND CASES:
+        // no custom config file name set - file name should be d.Path + "*.webconfig"
+        check "#1" null null <| 
+            fun (d, r) ->
+                let expectedPath = d.Path  ++ "*.config"
+                Assert.AreEqual(expectedPath, r.Path)
+
+        // no custom config file name set + resolutionfolder is specified- result file name should be d.Path + resolutionFolder + "*.webconfig"
+        check "#2" "Subfolder" null <| 
+            fun (d, r) ->
+                let expectedPath = d.Path  ++ "Subfolder" ++"*.config"
+                Assert.AreEqual(expectedPath, r.Path)
+
+        // no custom config file name set + absolute resolutionfolder is specified- result file name should be resolutionFolder + "*.webconfig"
+        (
+            use root = Util.TemporaryDirectory()
+            let absResolutionFolder = root.Path ++ "Subfolder2"
+            check "#3" absResolutionFolder null <|
+                fun (_, r) ->
+                    let expectedPath = absResolutionFolder ++"*.config"
+                    Assert.AreEqual(expectedPath, r.Path)
+        )
+
+        // absolute custom config file name set - result file name should be absolute 
+        (
+            use root = Util.TemporaryDirectory()
+            let absoluteConfigPath = root.Path ++ "somefolder" ++ "custom.config"
+            check "#4" null absoluteConfigPath <|
+                fun (_, r) -> Assert.AreEqual(absoluteConfigPath, r.Path)
+        )
+
+        // absolute custom config file name set - result file name should be absolute 
+        (
+            use root = Util.TemporaryDirectory()
+            let absoluteConfigPath = root.Path ++ "somefolder" ++ "custom.config"
+            check "#4.1" "some name" absoluteConfigPath <|
+                fun (_, r) -> Assert.AreEqual(absoluteConfigPath, r.Path)
+        )
+
+        // resolutionFolder + relative custom config file name set - result file name should be d.Path + resFolder + config file name
+        check "#5" "Subfolder" "custom.config" <|
+            fun (d, r) -> 
+                let expected = d.Path ++ "Subfolder" ++ "custom.config"
+                Assert.AreEqual(expected, r.Path)
+
+        // relative custom config file name set - result file name should be d.Path + config file name
+        check "#6" null "custom.config" <|
+            fun (d, r) -> 
+                let expected = d.Path ++  "custom.config"
+                Assert.AreEqual(expected, r.Path)
+
+        // resolution folder is absolute and config filename is relative - result file name should be resolution folder + config file name
+        (
+            use root = Util.TemporaryDirectory()
+            check "#7" root.Path "custom.config" <|
+                fun (_, r) ->
+                    let expected = root.Path ++ "custom.config"
+                    Assert.AreEqual(expected, r.Path)
+        )
+
+        // FOUND cases
+        let checkFound caption resFolder configFile actualConfigPath =
+            printfn "Running %s" caption
+            use d = Util.TemporaryDirectory()
+            let configPath = actualConfigPath d.Path
+
+            Directory.CreateDirectory(Path.GetDirectoryName configPath) 
+            |> ignore
+
+            File.WriteAllText(configPath, "")
+            let pru = Microsoft.FSharp.Data.TypeProviders.DesignTime.PathResolutionUtils(d.Path)
+            match pru.GetConfigFileWatchSpec(resFolder, configFile, "Name") with
+            | [r] -> Assert.AreEqual(configPath, r.Path)
+            | x -> sprintf "%s, unexpected result %A" caption x |> Assert.Fail
+            let di = DirectoryInfo d.Path
+            for subdir in di.GetDirectories() do
+                subdir.Delete(true)
+
+            printfn "Finished %s" caption
+        
+        // no res folder\no custom config
+        checkFound "#8" null null <| fun d -> d ++ "app.config"
+        // relative res folder\no custom config
+        checkFound "#9" "subfolder" null <| fun d -> d ++ "subfolder\\web.config"
+        // abs res folder\no custom config
+        (
+            use root = Util.TemporaryDirectory()
+            checkFound "#10" root.Path null <| fun _ -> root.Path ++ "app.config"
+        )
+
+        // no res folder\rel custom config
+        (
+            use root = Util.TemporaryDirectory()
+            let custom = root.Path ++ "custom.config"
+            checkFound "#11" null custom <| fun _ -> custom
+        )
+
+        // no res folder\abs custom config
+        (
+            use root = Util.TemporaryDirectory()
+            let custom = root.Path ++ "custom.config"
+            checkFound "#11" null custom <| fun _ -> custom
+        )
+
+        // relative res folder\relative custom config
+        checkFound "#12" "custom" @"sub\custom.config" <| fun d -> d ++ "custom" ++ @"sub\custom.config"
+
+        // relative res folder\absolute custom config
+        (
+            use root = Util.TemporaryDirectory()
+            let custom = root.Path ++ "custom.config"
+            checkFound "#13" "custom" custom <| fun _ -> custom
+        )
+
+        // abs res folder\absolute custom config
+        (
+            use resFolder = Util.TemporaryDirectory()
+            use configFolder = Util.TemporaryDirectory()
+            let custom = configFolder.Path ++ "custom.config"
+            checkFound "#14" resFolder.Path custom <| fun _ -> custom
+        )
+
+    [<Test>]
+    member public this.``ConfigFiles.findConfigFile``() = 
+        let withTempFile name f = 
+            use d = Util.TemporaryDirectory()
+            File.WriteAllText(Path.Combine(d.Path, name), "content")
+            f d.Path
+        let checkStandard name = 
+            withTempFile name <| fun folder ->
+                printfn "folder %s" folder
+                let r = CF.findConfigFile(folder, null)
+                match r with 
+                | CF.StandardFound f -> Assert.IsTrue(Path.GetFileName(f) = name)
+                | r -> sprintf "findConfigFile: StandardFound (%s)  unexpected result when: %+A" name r |> Assert.Fail
+        // check if app.config can be found
+        checkStandard "app.config"
+        // check if web.config can be found
+        checkStandard "web.config"
+
+        // check if proper result is returned is failure case when custom configuration file is not specified 
+        (
+            use td = Util.TemporaryDirectory()
+            let r = CF.findConfigFile(td.Path, null)
+            match r with
+            | CF.StandardNotFound -> ()
+            | r -> sprintf "findConfigFile: StandardNotFound - unexpected result: %+A" r |> Assert.Fail
+        )
+
+        // check if custom.config can be found
+        let customConfigName = "custom.config"
+        withTempFile customConfigName <| fun folder ->
+            let r = CF.findConfigFile(folder, Path.Combine(folder, customConfigName))
+            match r with 
+            | CF.CustomFound f -> Assert.IsTrue(Path.GetFileName(f) = customConfigName)
+            | r -> sprintf "findConfigFile: CustomFound (%s)  unexpected result when: %+A" customConfigName r |> Assert.Fail
+
+        // check if proper result is returned is failure case when custom configuration file is specified 
+        (
+            use td = Util.TemporaryDirectory()
+            let r = CF.findConfigFile(td.Path, Path.Combine(td.Path, customConfigName))
+            match r with
+            | CF.CustomNotFound _ -> ()
+            | r -> sprintf "findConfigFile: CustomNotFound - unexpected result: %+A" r |> Assert.Fail
+        )
+
+    [<Test>]
+    member public this.``ConfigFiles.tryReadConnectionString``() = 
+        // 1. no file found
+        (
+            use dir = Util.TemporaryDirectory()
+            let r = CF.tryReadConnectionString(Path.Combine(dir.Path, "app.config"), "F")
+            match r with
+            | CF.ConnectionStringReadResult.Error (:? FileNotFoundException) -> ()
+            | r -> sprintf "no file found: unexpected result - %+A" r |> Assert.Fail
+        )
+
+        // 2.  file exists but corrupted
+        (
+            use f = Util.TemporaryFile "app.config"
+            File.WriteAllText(f.Path, "some text")
+            let r = CF.tryReadConnectionString(f.Path, "F")
+            match r with
+            | CF.ConnectionStringReadResult.Error e -> printfn "%A" e
+            | r -> sprintf "file exists but corrupted: unexpected result - %+A" r |> Assert.Fail
+        )
+
+        // 3. file is correct but doesn't contain connection string
+        (
+            let configText = """
+<?xml version="1.0" encoding="utf-8"?>
+<configuration>
+  <startup>
+    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0" />
+  </startup>
+</configuration>"""
+            use f = Util.TemporaryFile "app.config"
+            File.WriteAllText(f.Path, configText.Trim())
+            let r = CF.tryReadConnectionString(f.Path, "F")
+            match r with
+            | CF.ConnectionStringReadResult.NotFound -> ()
+            | r -> sprintf "file is correct but doesn't contain connection string: unexpected result - %+A" r |> Assert.Fail
+        )
+
+        // 4. file is correct and it contains connection string
+        (
+            let configText = """
+<?xml version="1.0" encoding="utf-8" ?>
+<configuration>
+  <connectionStrings>
+    <add name="S" connectionString="string"/>
+  </connectionStrings>
+</configuration>"""
+            use f = Util.TemporaryFile "app.config"
+            File.WriteAllText(f.Path, configText.Trim())
+            let r = CF.tryReadConnectionString(f.Path, "S")
+            match r with
+            | CF.ConnectionStringReadResult.Ok s -> Assert.AreEqual("string", s.ConnectionString)
+            | r -> sprintf "file is correct but doesn't contain connection string: unexpected result - %+A" r |> Assert.Fail
+        
+        )
diff --git a/vsintegration/src/unittests/Tests.Watson.fs b/vsintegration/src/unittests/Tests.Watson.fs
new file mode 100644
index 0000000..3f20230
--- /dev/null
+++ b/vsintegration/src/unittests/Tests.Watson.fs
@@ -0,0 +1,169 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+namespace UnitTests.Tests
+
+(*
+    Is NUNIT just disappearing when you run one of these tests?
+    There are paths in the compiler that call Process.Exit, if we manage to hit one of these paths then the process (nunit-gui.exe)
+    will be exited:
+    
+    Put a break point on:
+    
+        System.Environment.Exit(n)  
+*)    
+
+#nowarn "52" // The value has been copied to ensure the original is not mutated
+
+open NUnit.Framework
+open System
+open System.Text.RegularExpressions 
+open System.Diagnostics
+open System.Collections.Generic
+open System.IO
+open System.Reflection
+
+type Check = 
+    static member public FscLevelException<'TException when 'TException :> exn>(simulationCode)  =
+        try 
+            try
+#if DEBUG
+                Microsoft.FSharp.Compiler.Build.FullCompiler.showAssertForUnexpectedException := false
+#endif
+                if (File.Exists("watson-test.fs")) then
+                    File.Delete("watson-test.fs")
+                File.WriteAllText("watson-test.fs", "// Hello watson" )
+                let _code = Microsoft.FSharp.Compiler.CommandLineMain.main([| "--simulateException:"+simulationCode; "watson-test.fs"|]) 
+                ()
+            with 
+            | :? 'TException as e -> 
+                let msg = e.ToString();
+                if msg.Contains("ReportTime") || msg.Contains("TypecheckOneInput") then ()
+                else
+                    printfn "%s" msg
+                    Assert.Fail("The correct callstack was not reported to watson.")
+        finally               
+#if DEBUG
+            Microsoft.FSharp.Compiler.Build.FullCompiler.showAssertForUnexpectedException := true
+#endif
+        File.Delete("watson-test.fs")
+
+
+[<TestFixture>] 
+type Watson() = 
+
+    [<Test>]
+    member public w.FscOutOfMemory() = Check.FscLevelException<System.OutOfMemoryException>("fsc-oom")
+
+    [<Test>]
+    member public w.FscArgumentNull() = Check.FscLevelException<System.ArgumentNullException>("fsc-an")        
+    
+    [<Test>]
+    member public w.FscInvalidOperation() = Check.FscLevelException<System.InvalidOperationException>("fsc-invop")        
+
+// As of .NET 4.0 some exception types cannot be caught. As a result, we cannot test this case. I did visually confirm a Watson report is sent, though.
+//    [<Test>]
+//    member public w.FscAccessViolation() = Check.FscLevelException<System.AccessViolationException>("fsc-ac")        
+
+    [<Test>]
+    member public w.FscArgumentOutOfRange() = Check.FscLevelException<System.ArgumentOutOfRangeException>("fsc-aor")        
+
+    [<Test>]
+    member public w.FscDivideByZero() = Check.FscLevelException<System.DivideByZeroException>("fsc-dv0")        
+
+    [<Test>]
+    member public w.FscNotFiniteNumber() = Check.FscLevelException<System.NotFiniteNumberException>("fsc-nfn")        
+
+    [<Test>]
+    member public w.FscOverflow() = Check.FscLevelException<System.OverflowException>("fsc-oe")        
+
+    [<Test>]
+    member public w.FscArrayTypeMismatch() = Check.FscLevelException<System.ArrayTypeMismatchException>("fsc-atmm")        
+
+    [<Test>]
+    member public w.FscBadImageFormat() = Check.FscLevelException<System.BadImageFormatException>("fsc-bif")        
+
+    [<Test>]
+    member public w.FscKeyNotFound() = Check.FscLevelException<System.Collections.Generic.KeyNotFoundException>("fsc-knf")        
+
+    [<Test>]
+    member public w.FscIndexOutOfRange() = Check.FscLevelException<System.IndexOutOfRangeException>("fsc-ior")        
+
+    [<Test>]
+    member public w.FscInvalidCast() = Check.FscLevelException<System.InvalidCastException>("fsc-ic")        
+
+    [<Test>]
+    member public w.FscInvalidProgram() = Check.FscLevelException<System.InvalidProgramException>("fsc-ip")        
+
+    [<Test>]
+    member public w.FscMemberAccess() = Check.FscLevelException<System.MemberAccessException>("fsc-ma")        
+
+    [<Test>]
+    member public w.FscNotImplemented() = Check.FscLevelException<System.NotImplementedException>("fsc-ni")        
+
+    [<Test>]
+    member public w.FscNullReference() = Check.FscLevelException<System.NullReferenceException>("fsc-nr")        
+
+    [<Test>]
+    member public w.FscOperationCancelled() = Check.FscLevelException<System.OperationCanceledException>("fsc-oc")        
+    
+    //[<Test>]
+    //member public w.FscFailure() = Check.FscLevelException<Microsoft.FSharp.Core.FailureException>("fsc-fail")            
+      
+    [<Test>]
+    member public w.TypeCheckOutOfMemory() = Check.FscLevelException<System.OutOfMemoryException>("tc-oom")
+
+    [<Test>]
+    member public w.TypeCheckArgumentNull() = Check.FscLevelException<System.ArgumentNullException>("tc-an")        
+    
+    [<Test>]
+    member public w.TypeCheckInvalidOperation() = Check.FscLevelException<System.InvalidOperationException>("tc-invop")        
+
+// As of .NET 4.0 some exception types cannot be caught. As a result, we cannot test this case. I did visually confirm a Watson report is sent, though.
+//    [<Test>]
+//    member public w.TypeCheckAccessViolation() = Check.FscLevelException<System.AccessViolationException>("tc-ac")        
+
+    [<Test>]
+    member public w.TypeCheckArgumentOutOfRange() = Check.FscLevelException<System.ArgumentOutOfRangeException>("tc-aor")        
+
+    [<Test>]
+    member public w.TypeCheckDivideByZero() = Check.FscLevelException<System.DivideByZeroException>("tc-dv0")        
+
+    [<Test>]
+    member public w.TypeCheckNotFiniteNumber() = Check.FscLevelException<System.NotFiniteNumberException>("tc-nfn")        
+
+    [<Test>]
+    member public w.TypeCheckOverflow() = Check.FscLevelException<System.OverflowException>("tc-oe")        
+
+    [<Test>]
+    member public w.TypeCheckArrayTypeMismatch() = Check.FscLevelException<System.ArrayTypeMismatchException>("tc-atmm")        
+
+    [<Test>]
+    member public w.TypeCheckBadImageFormat() = Check.FscLevelException<System.BadImageFormatException>("tc-bif")        
+
+    [<Test>]
+    member public w.TypeCheckKeyNotFound() = Check.FscLevelException<System.Collections.Generic.KeyNotFoundException>("tc-knf")        
+
+    [<Test>]
+    member public w.TypeCheckIndexOutOfRange() = Check.FscLevelException<System.IndexOutOfRangeException>("tc-ior")        
+
+    [<Test>]
+    member public w.TypeCheckInvalidCast() = Check.FscLevelException<System.InvalidCastException>("tc-ic")        
+
+    [<Test>]
+    member public w.TypeCheckInvalidProgram() = Check.FscLevelException<System.InvalidProgramException>("tc-ip")        
+
+    [<Test>]
+    member public w.TypeCheckMemberAccess() = Check.FscLevelException<System.MemberAccessException>("tc-ma")        
+
+    [<Test>]
+    member public w.TypeCheckNotImplemented() = Check.FscLevelException<System.NotImplementedException>("tc-ni")        
+
+    [<Test>]
+    member public w.TypeCheckNullReference() = Check.FscLevelException<System.NullReferenceException>("tc-nr")        
+
+    [<Test>]
+    member public w.TypeCheckOperationCancelled() = Check.FscLevelException<System.OperationCanceledException>("tc-oc")        
+
+    [<Test>]
+    member public w.TypeCheckFailure() = Check.FscLevelException<System.Exception>("tc-fail")            
+
diff --git a/vsintegration/src/unittests/Tests.XmlDocComments.fs b/vsintegration/src/unittests/Tests.XmlDocComments.fs
new file mode 100644
index 0000000..e41b317
--- /dev/null
+++ b/vsintegration/src/unittests/Tests.XmlDocComments.fs
@@ -0,0 +1,102 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
+namespace UnitTests.Tests
+
+open System
+open NUnit.Framework
+open Salsa.Salsa
+open Salsa.VsOpsUtils
+open UnitTests.TestLib.Salsa
+open UnitTests.TestLib.Utils
+
+[<TestFixture>]
+type XmlDocComments() = 
+    inherit UnitTests.TestLib.LanguageService.LanguageServiceBaseTests(VsOpts = fst (Models.InstalledMSBuild()))
+    // Work around an innocuous 'feature' with how QuickInfo is displayed, lines which 
+    // should have a "\r\n" just have a "\r"
+    let trimnewlines (str : string) = 
+        str.Replace("\r", "").Replace("\n", "")    
+
+    member public this.AssertQuickInfoContainsAtStartOfMarker code marker expected =
+        let (_solution, _project, file) = this.CreateSingleFileProject(code : string)
+        MoveCursorToStartOfMarker(file, marker)
+        let tooltip = GetQuickInfoAtCursor file 
+        printfn "%A" tooltip
+        AssertContains(trimnewlines tooltip, trimnewlines expected) 
+
+    member private this.TestMalFormedXML(marker : string) =   
+        let fileContent1 = """
+            namespace XML
+            module Doc =
+                /// <summary>
+                /// Adds two <see cref="T:System.Int32" /> values.
+                /// </summary>
+                /// <param name="x">The first value to sum</param>
+                /// <param name="x">The second value to sum</param
+                let Add x y= x + y"""
+        let fileContent2 = """
+            module XMLDoc
+            /// <summary>
+            /// Subtract two <see cref="T:System.Int32" /> values.
+            /// <summary>
+            let Subtract x y = x - y
+
+            /// <summary>
+            /// Multipy two <see cref="T:System.Int32" /> values.
+            /// </summary>
+            /// <param name="x">The first value to sum</param>
+            /// <param name="x">The second value to sum</param>
+            let Multipy x y = x * y
+
+            let foo = XML.Doc.Add(*Marker1*)
+            let bar = Subtract(*Marker2*) 3 2
+            let baz = Multipy(*Marker3*) 2 3"""
+        use _guard = this.UsingNewVS()
+        let solution = this.CreateSolution()
+        let project1 = CreateProject(solution, "FSLibrary")
+        let project2 = CreateProject(solution, "FSClient")
+        let file1 = AddFileFromTextBlob(project1,"File1.fs", fileContent1)
+        AddProjectReference(project2,project1)       
+        Build(project1) |> fun result -> Assert.IsTrue(result.BuildSucceeded)
+
+        let file2 = AddFileFromTextBlob(project2,"File2.fs", fileContent2)
+        let file = OpenFile(project2, "File2.fs")
+        MoveCursorToStartOfMarker(file, marker)
+        GetQuickInfoAtCursor file
+
+    [<Test>]
+    [<Ignore("GetQcuickInfoAtCursor miss XMLDoc analyzing")>]
+    member this.``MalFormedXML.FromXMLDoc``() = 
+        let expected = "XML comment"
+        let tooltip = this.TestMalFormedXML("(*Marker1*)")
+        printfn "%A" tooltip
+        AssertContains(trimnewlines tooltip, trimnewlines expected) 
+
+    [<Test>]
+    [<Ignore("GetQcuickInfoAtCursor miss XMLDoc analyzing")>]
+    member this.``MalFormedXML.FromCurrentProject``() = 
+        let expected = "'summary'"
+        let tooltip = this.TestMalFormedXML("(*Marker2*)")
+        printfn "%A" tooltip
+        AssertContains(trimnewlines tooltip, trimnewlines expected) 
+
+    [<Test>]
+    [<Ignore("GetQcuickInfoAtCursor miss XMLDoc analyzing")>]
+    member this.``MalFormedXML.NoXMLComment.Bug5858``() = 
+        let notexpected = "summary"
+        let notexpected2 = "param name="
+        let tooltip = this.TestMalFormedXML("(*Marker3*)")
+        printfn "%A" tooltip
+        AssertNotContains(tooltip, notexpected)   
+        AssertNotContains(tooltip, notexpected2)   
+
+    [<Test>]
+    [<Ignore("GetQcuickInfoAtCursor miss XMLDoc analyzing")>]
+    member this.Test() = 
+        let fileContent = """
+            //local custom type value
+            /// <summary>
+            /// local custom value
+            /// </summary>
+            let customType(*Mark*) = new CustomType()"""
+        this.AssertQuickInfoContainsAtStartOfMarker fileContent "(*Mark*)" "local custom value"
\ No newline at end of file
diff --git a/vsintegration/src/unittests/Unittests.dll.config b/vsintegration/src/unittests/Unittests.dll.config
new file mode 100644
index 0000000..c27b1df
--- /dev/null
+++ b/vsintegration/src/unittests/Unittests.dll.config
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information. -->
+<configuration>
+    <appSettings>
+        <add key="fsharp-compiler-location" value="{FinalDir}" />
+    </appSettings>
+    <runtime>
+        <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
+            <dependentAssembly>
+                <assemblyIdentity name="Microsoft.Build.Framework" publicKeyToken="b03f5f7f11d50a3a" culture="neutral"/>
+                <bindingRedirect oldVersion="0.0.0.0-99.9.9.9" newVersion="12.0.0.0"/>
+            </dependentAssembly>
+        </assemblyBinding>
+        <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
+          <dependentAssembly>
+            <assemblyIdentity name="EnvDTE" publicKeyToken="b03f5f7f11d50a3a" culture="neutral"/>
+            <bindingRedirect oldVersion="7.0.3300.0" newVersion="8.0.0.0"/>
+          </dependentAssembly>
+            <dependentAssembly>
+                <assemblyIdentity name="Microsoft.VisualStudio.Package.LanguageService.10.0" publicKeyToken="b03f5f7f11d50a3a" culture="neutral"/>
+                <bindingRedirect oldVersion="2.0.0.0-11.0.0.0" newVersion="10.0.0.0"/>
+            </dependentAssembly>
+            <dependentAssembly>
+                <assemblyIdentity name="Microsoft.VisualStudio.Shell.10.0" publicKeyToken="b03f5f7f11d50a3a" culture="neutral"/>
+                <bindingRedirect oldVersion="2.0.0.0-10.0.0.0" newVersion="11.0.0.0"/>
+            </dependentAssembly>
+            <dependentAssembly>
+                <assemblyIdentity name="Microsoft.Build" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
+                <bindingRedirect oldVersion="0.0.0.0-12.0.0.0" newVersion="12.0.0.0" />            
+            </dependentAssembly>
+            <dependentAssembly>
+              <assemblyIdentity name="FSharp.Core" publicKeyToken="b03f5f7f11d50a3a" culture="neutral"/>
+              <bindingRedirect oldVersion="4.3.0.0" newVersion="4.3.1.9055"/>
+            </dependentAssembly>
+        </assemblyBinding>
+    </runtime>
+</configuration>
diff --git a/vsintegration/src/unittests/Unittests.fsproj b/vsintegration/src/unittests/Unittests.fsproj
new file mode 100644
index 0000000..5055eb2
--- /dev/null
+++ b/vsintegration/src/unittests/Unittests.fsproj
@@ -0,0 +1,170 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information. -->
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <FSharpSourcesRoot>..\..\..\src</FSharpSourcesRoot>
+    <vsFrameworkLatest>Microsoft.VisualStudio.Shell.12.0</vsFrameworkLatest>
+    <ProjectLanguage>FSharp</ProjectLanguage>
+    <SIGN_WITH_MSFT_KEY>true</SIGN_WITH_MSFT_KEY>
+  </PropertyGroup>
+  <Import Project="$(FSharpSourcesRoot)\FSharpSource.settings.targets" />
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{EE85AAB7-CDA0-4C4E-BDA0-A64DDDD13E3F}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AssemblyName>Unittests</AssemblyName>
+    <GenerateInterfaceFile>Unittests.fsi</GenerateInterfaceFile>
+    <TargetType>LIBRARY</TargetType>
+    <NoWarn>58;75</NoWarn>
+  </PropertyGroup>
+  <ItemGroup>
+    <Compile Include="$(FSharpSourcesRoot)\fsharp\InternalCollections.fsi">
+      <Link>Internal.Utilities.Collections.fsi</Link>
+    </Compile>
+    <Compile Include="$(FSharpSourcesRoot)\fsharp\InternalCollections.fs">
+      <Link>Internal.Utilities.Collections.fs</Link>
+    </Compile>
+    <Compile Include="$(FSharpSourcesRoot)\utils\CompilerLocationUtils.fs">
+      <Link>Internal.Utilities.CompilerLocationUtils.fs</Link>
+    </Compile>
+    <Compile Include="TestLib.Utils.fs" />
+    <Compile Include="TestLib.Salsa.fs" />
+    <Compile Include="TestLib.LanguageService.fs" />
+    <Compile Include="TestLib.ProjectSystem.fs" />
+    <Compile Include="Tests.InternalCollections.fs" />
+    <Compile Include="Tests.Build.fs" />
+    <Compile Include="Tests.TypeProvidersImpl.fs" />
+    <Compile Include="Tests.BaseLine.fs" />
+    <Compile Include="Tests.TaskReporter.fs" />
+    <Compile Include="Tests.Watson.fs" />
+    <Compile Include="Tests.XmlDocComments.fs" />
+    <Compile Include="Tests.LanguageService.General.fs" />
+    <Compile Include="Tests.LanguageService.Colorizer.fs" />
+    <Compile Include="Tests.LanguageService.Completion.fs" />
+    <Compile Include="Tests.LanguageService.F1Keyword.fs" />
+    <Compile Include="Tests.LanguageService.IncrementalBuild.fs" />
+    <Compile Include="Tests.LanguageService.GotoDefinition.fs" />
+    <Compile Include="Tests.LanguageService.NavigationBar.fs" />
+    <Compile Include="Tests.LanguageService.ParameterInfo.fs" />
+    <Compile Include="Tests.LanguageService.QuickInfo.fs" />
+    <Compile Include="Tests.LanguageService.QuickParse.fs" />
+    <Compile Include="Tests.LanguageService.Script.fs" />
+    <Compile Include="Tests.LanguageService.Squiggles.fs" />
+    <Compile Include="Tests.LanguageService.TimeStamp.fs" />
+    <Compile Include="Tests.LanguageService.ErrorList.fs" />
+    <Compile Include="Tests.LanguageService.ErrorRecovery.fs" />
+    <Compile Include="Tests.ProjectSystem.Configs.fs" />
+    <Compile Include="Tests.ProjectSystem.Miscellaneous.fs" />
+    <Compile Include="Tests.ProjectSystem.MultiTargeting.fs" />
+    <Compile Include="Tests.ProjectSystem.ProjectItems.fs" />
+    <Compile Include="Tests.ProjectSystem.Project.fs" />
+    <Compile Include="Tests.ProjectSystem.References.fs" />
+    <Compile Include="Tests.ProjectSystem.RoundTrip.fs" />
+    <CustomCopyLocal Include="Unittests.dll.config">
+        <TargetFilename>Unittests.dll.config</TargetFilename>
+    </CustomCopyLocal>
+  </ItemGroup>
+  <ItemGroup>
+    <Reference Include="mscorlib" />
+    <Reference Include="System" />
+    <Reference Include="System.Numerics" />
+    <Reference Include="System.Windows.Forms" />
+    <Reference Include="System.Drawing" />
+    <Reference Include="System.Configuration" />
+    <Reference Include="System.Xml" />
+    <Reference Include="System.Xml.Linq" />
+    <Reference Include="PresentationCore" />
+    <Reference Include="PresentationFramework" />
+    <Reference Include="System.Xaml" />
+    <Reference Include="WindowsBase" />
+    <Reference Include="UIAutomationTypes" />
+    <Reference Include="Microsoft.Build, Version=12.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+      <SpecificVersion>true</SpecificVersion>
+    </Reference>
+    <Reference Include="Microsoft.Build.Engine, Version=12.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+      <SpecificVersion>true</SpecificVersion>
+    </Reference>
+    <Reference Include="Microsoft.Build.Framework, Version=12.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+      <SpecificVersion>true</SpecificVersion>
+    </Reference>
+    <Reference Include="Microsoft.Build.Utilities.v12.0" />
+    <Reference Include="Microsoft.Build.Utilities.v3.5.dll" />
+    <Reference Include="EnvDTE.dll" />
+    <Reference Include="EnvDTE80.dll" />
+    <Reference Include="VSLangProj" />
+    <Reference Include="VSLangProj80" />
+    <Reference Include="Microsoft.VisualStudio.OLE.Interop.dll" />
+    <Reference Include="$(vsFrameworkLatest)" />
+    <Reference Include="Microsoft.VisualStudio.Threading" />
+    <Reference Include="Microsoft.VisualStudio.Shell.Interop.8.0.dll" />
+    <Reference Include="Microsoft.VisualStudio.Shell.Interop.9.0.dll" />
+    <Reference Include="Microsoft.VisualStudio.Shell.Interop.10.0.dll" />
+    <Reference Include="Microsoft.VisualStudio.Shell.Interop.11.0.dll" />
+    <Reference Include="Microsoft.VisualStudio.Shell.Interop.dll" />
+    <Reference Include="Microsoft.VisualStudio.Shell.Design" />
+    <Reference Include="Microsoft.VisualStudio.ProjectAggregator" />
+    <Reference Include="Microsoft.VisualStudio.TextManager.Interop.dll" />
+    <Reference Include="Microsoft.VisualStudio.Text.Data.dll" />
+    <Reference Include="Microsoft.VisualStudio.TextManager.Interop.8.0.dll" />
+    <Reference Include="Microsoft.VisualStudio.Designer.Interfaces" />
+    <Reference Include="Microsoft.VisualStudio.CommonIDE" />
+    <Reference Include="Microsoft.VisualStudio.VSHelp.dll" />
+    <Reference Include="nunit.framework.dll" />
+    <ProjectReference Include="$(FSharpSourcesRoot)\fsharp\Fsc\Fsc.fsproj">
+      <Project>{ffde9e47-9675-4498-b540-69b2583dd600}</Project>
+      <Name>Fsc</Name>
+    </ProjectReference>
+    <ProjectReference Include="$(FSharpSourcesRoot)\fsharp\FSharp.Core\FSharp.Core.fsproj">
+      <Project>{DED3BBD7-53F4-428A-8C9F-27968E768605}</Project>
+      <Name>FSharp.Core</Name>
+    </ProjectReference>
+    <ProjectReference Include="$(FSharpSourcesRoot)\fsharp\FSharp.Build\FSharp.Build.fsproj">
+      <Name>FSharp.Build</Name>
+      <Project>{702a7979-bcf9-4c41-853e-3adfc9897890}</Project>
+      <Private>True</Private>
+    </ProjectReference>
+    <ProjectReference Include="$(FSharpSourcesRoot)\fsharp\FSharp.Compiler\FSharp.Compiler.fsproj">
+      <Project>{2E4D67B4-522D-4CF7-97E4-BA940F0B18F3}</Project>
+      <Name>FSharp.Compiler</Name>
+      <Private>True</Private>
+    </ProjectReference>
+    <ProjectReference Include="$(FSharpSourcesRoot)\fsharp\FSharp.Data.TypeProviders\FSharp.Data.TypeProviders.fsproj">
+      <Project>{cb7d20c4-6506-406d-9144-5342c3595f03}</Project>
+      <Name>FSharp.Data.TypeProviders</Name>
+      <Private>True</Private>
+    </ProjectReference>
+    <ProjectReference Include="$(FSharpSourcesRoot)\fsharp\FSharp.LanguageService.Compiler\FSharp.LanguageService.Compiler.fsproj">
+      <Name>FSharp.LanguageService.Compiler</Name>
+      <Project>{a437a6ec-5323-47c2-8f86-e2cac54ff152}</Project>
+      <Private>True</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\vs\FsPkgs\FSharp.LanguageService\FSharp.LanguageService.Base\FSharp.LanguageService.Base.csproj">
+      <Name>FSharp.LanguageService.Base</Name>
+      <Project>{1c5c163c-37ea-4a3c-8ccc-0d34b74bf8ef}</Project>
+      <Private>True</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\vs\FsPkgs\FSharp.LanguageService\FSharp.LanguageService.fsproj">
+      <Name>FSharp.LanguageService</Name>
+      <Project>{ee85aab7-cda0-4c4e-bda0-a64ccc413e3f}</Project>
+      <Private>True</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\vs\FsPkgs\FSharp.Project\Common.Source.CSharp\Project\ProjectSystem.Base.csproj">
+      <Name>ProjectSystem.Base</Name>
+      <Project>{b700e38b-f8c0-4e49-b5ec-db7b7ac0c4e7}</Project>
+      <Private>True</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\vs\FsPkgs\FSharp.Project\FS\ProjectSystem.fsproj">
+      <Name>FSharp.ProjectSystem.FSharp</Name>
+      <Project>{6196B0F8-CAEA-4CF1-AF82-1B520F77FE44}</Project>
+      <Private>True</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\Salsa\Salsa.fsproj">
+      <Name>Salsa</Name>
+      <Project>{fbd4b354-dc6e-4032-8ec7-c81d8dfb1af7}</Project>
+      <Private>True</Private>
+    </ProjectReference>
+  </ItemGroup>
+  <Import Project="$(FSharpSourcesRoot)\FSharpSource.targets" />
+</Project>
\ No newline at end of file
diff --git a/vsintegration/src/vs/FsPkgs/FSharp.LanguageService/FSharp.LanguageService.Base/CodeWindowManager.cs b/vsintegration/src/vs/FsPkgs/FSharp.LanguageService/FSharp.LanguageService.Base/CodeWindowManager.cs
index 1404f3b..b14a4b2 100644
--- a/vsintegration/src/vs/FsPkgs/FSharp.LanguageService/FSharp.LanguageService.Base/CodeWindowManager.cs
+++ b/vsintegration/src/vs/FsPkgs/FSharp.LanguageService/FSharp.LanguageService.Base/CodeWindowManager.cs
@@ -1,3 +1,5 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
 using System;
 using System.Collections;
 using System.Diagnostics;
diff --git a/vsintegration/src/vs/FsPkgs/FSharp.LanguageService/Source.fs b/vsintegration/src/vs/FsPkgs/FSharp.LanguageService/Source.fs
index b236115..d695cbe 100644
--- a/vsintegration/src/vs/FsPkgs/FSharp.LanguageService/Source.fs
+++ b/vsintegration/src/vs/FsPkgs/FSharp.LanguageService/Source.fs
@@ -1,3 +1,5 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
 #nowarn "40"
 
 namespace Microsoft.VisualStudio.FSharp.LanguageService
diff --git a/vsintegration/src/vs/FsPkgs/FSharp.Project/Common.Source.CSharp/Project/Automation/OAFileItem.cs b/vsintegration/src/vs/FsPkgs/FSharp.Project/Common.Source.CSharp/Project/Automation/OAFileItem.cs
index cbeceaa..7540edb 100644
--- a/vsintegration/src/vs/FsPkgs/FSharp.Project/Common.Source.CSharp/Project/Automation/OAFileItem.cs
+++ b/vsintegration/src/vs/FsPkgs/FSharp.Project/Common.Source.CSharp/Project/Automation/OAFileItem.cs
@@ -1,13 +1,4 @@
-/***************************************************************************
-
-Copyright (c) Microsoft Corporation. All rights reserved.
-This code is licensed under the Visual Studio SDK license terms.
-THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
-ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
-IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
-PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
-
-***************************************************************************/
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
 
 using System;
 using Microsoft.VisualStudio.Shell.Interop;
diff --git a/vsintegration/src/vs/FsPkgs/FSharp.Project/Common.Source.CSharp/RegistrationAttributes/CodeGeneratorRegistrationAttribute.cs b/vsintegration/src/vs/FsPkgs/FSharp.Project/Common.Source.CSharp/RegistrationAttributes/CodeGeneratorRegistrationAttribute.cs
index db34667..0602661 100644
--- a/vsintegration/src/vs/FsPkgs/FSharp.Project/Common.Source.CSharp/RegistrationAttributes/CodeGeneratorRegistrationAttribute.cs
+++ b/vsintegration/src/vs/FsPkgs/FSharp.Project/Common.Source.CSharp/RegistrationAttributes/CodeGeneratorRegistrationAttribute.cs
@@ -1,13 +1,4 @@
-/***************************************************************************
-
-Copyright (c) Microsoft Corporation. All rights reserved.
-This code is licensed under the Visual Studio SDK license terms.
-THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
-ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
-IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
-PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
-
-***************************************************************************/
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
 
 using System;
 using System.Globalization;
diff --git a/vsintegration/src/vs/FsPkgs/FSharp.Project/Common.Source.CSharp/RegistrationAttributes/ComponentPickerPropertyPageAttribute.cs b/vsintegration/src/vs/FsPkgs/FSharp.Project/Common.Source.CSharp/RegistrationAttributes/ComponentPickerPropertyPageAttribute.cs
index f3c9958..70b9c6b 100644
--- a/vsintegration/src/vs/FsPkgs/FSharp.Project/Common.Source.CSharp/RegistrationAttributes/ComponentPickerPropertyPageAttribute.cs
+++ b/vsintegration/src/vs/FsPkgs/FSharp.Project/Common.Source.CSharp/RegistrationAttributes/ComponentPickerPropertyPageAttribute.cs
@@ -1,13 +1,4 @@
-/***************************************************************************
-
-Copyright (c) Microsoft Corporation. All rights reserved.
-This code is licensed under the Visual Studio SDK license terms.
-THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
-ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
-IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
-PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
-
-***************************************************************************/
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
 
 using System;
 using System.Globalization;
diff --git a/vsintegration/src/vs/FsPkgs/FSharp.Project/Common.Source.CSharp/RegistrationAttributes/EditorFactoryNotifyForProjectAttribute.cs b/vsintegration/src/vs/FsPkgs/FSharp.Project/Common.Source.CSharp/RegistrationAttributes/EditorFactoryNotifyForProjectAttribute.cs
index 4066b59..5a43b38 100644
--- a/vsintegration/src/vs/FsPkgs/FSharp.Project/Common.Source.CSharp/RegistrationAttributes/EditorFactoryNotifyForProjectAttribute.cs
+++ b/vsintegration/src/vs/FsPkgs/FSharp.Project/Common.Source.CSharp/RegistrationAttributes/EditorFactoryNotifyForProjectAttribute.cs
@@ -1,13 +1,4 @@
-//***************************************************************************
-//
-//    Copyright (c) Microsoft Corporation. All rights reserved.
-//    This code is licensed under the Visual Studio SDK license terms.
-//    THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
-//    ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
-//    IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
-//    PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
-//
-//***************************************************************************
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
 
 using System;
 using System.Globalization;
diff --git a/vsintegration/src/vs/FsPkgs/FSharp.Project/FS/AppConfigHelper.fs b/vsintegration/src/vs/FsPkgs/FSharp.Project/FS/AppConfigHelper.fs
index 729b84f..241fe6e 100644
--- a/vsintegration/src/vs/FsPkgs/FSharp.Project/FS/AppConfigHelper.fs
+++ b/vsintegration/src/vs/FsPkgs/FSharp.Project/FS/AppConfigHelper.fs
@@ -1,7 +1,4 @@
-//---------------------------------------------------------------------------------------
-// Copyright (c) Microsoft Corporation. All rights reserved.
-//---------------------------------------------------------------------------------------
-
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
 
 namespace Microsoft.VisualStudio.FSharp.ProjectSystem
 
diff --git a/vsintegration/src/vs/FsPkgs/FSharp.Project/FS/FSharp.ProjectSystem.FSharp.dll.config b/vsintegration/src/vs/FsPkgs/FSharp.Project/FS/FSharp.ProjectSystem.FSharp.dll.config
index 1f6f752..9545b79 100644
--- a/vsintegration/src/vs/FsPkgs/FSharp.Project/FS/FSharp.ProjectSystem.FSharp.dll.config
+++ b/vsintegration/src/vs/FsPkgs/FSharp.Project/FS/FSharp.ProjectSystem.FSharp.dll.config
@@ -1,3 +1,4 @@
+<!-- Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information. -->
 <configuration>
     <configSections>
         <section name="msbuildToolsets" type="Microsoft.Build.BuildEngine.ToolsetConfigurationSection, Microsoft.Build.Engine, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
diff --git a/vsintegration/src/vs/FsPkgs/FSharp.Project/FS/InternalsVisibleTo.fs b/vsintegration/src/vs/FsPkgs/FSharp.Project/FS/InternalsVisibleTo.fs
index 7fe6e00..49caf72 100644
--- a/vsintegration/src/vs/FsPkgs/FSharp.Project/FS/InternalsVisibleTo.fs
+++ b/vsintegration/src/vs/FsPkgs/FSharp.Project/FS/InternalsVisibleTo.fs
@@ -1,10 +1,19 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
 namespace Microsoft.FSharp
 open System.Reflection
-[<assembly:System.Runtime.CompilerServices.InternalsVisibleTo("FSharp.Build, PublicKey=002400000480000094000000060200000024000052534131000400000100010007D1FA57C4AED9F0A32E84AA0FAEFD0DE9E8FD6AEC8F87FB03766C834C99921EB23BE79AD9D5DCC1DD9AD236132102900B723CF980957FC4E177108FC607774F29E8320E92EA05ECE4E821C0A5EFE8F1645C4C0C93C1AB99285D622CAA652C1DFAD63D745D6F2DE5F17E5EAF0FC4963D261C8A12436518206DC093344D5AD293")>]
-[<assembly:System.Runtime.CompilerServices.InternalsVisibleTo("FSharp.QuickSearch, PublicKey=002400000480000094000000060200000024000052534131000400000100010007D1FA57C4AED9F0A32E84AA0FAEFD0DE9E8FD6AEC8F87FB03766C834C99921EB23BE79AD9D5DCC1DD9AD236132102900B723CF980957FC4E177108FC607774F29E8320E92EA05ECE4E821C0A5EFE8F1645C4C0C93C1AB99285D622CAA652C1DFAD63D745D6F2DE5F17E5EAF0FC4963D261C8A12436518206DC093344D5AD293")>]
-[<assembly:System.Runtime.CompilerServices.InternalsVisibleTo("Salsa, PublicKey=002400000480000094000000060200000024000052534131000400000100010007D1FA57C4AED9F0A32E84AA0FAEFD0DE9E8FD6AEC8F87FB03766C834C99921EB23BE79AD9D5DCC1DD9AD236132102900B723CF980957FC4E177108FC607774F29E8320E92EA05ECE4E821C0A5EFE8F1645C4C0C93C1AB99285D622CAA652C1DFAD63D745D6F2DE5F17E5EAF0FC4963D261C8A12436518206DC093344D5AD293")>]
-[<assembly:System.Runtime.CompilerServices.InternalsVisibleTo("Unittests, PublicKey=002400000480000094000000060200000024000052534131000400000100010007D1FA57C4AED9F0A32E84AA0FAEFD0DE9E8FD6AEC8F87FB03766C834C99921EB23BE79AD9D5DCC1DD9AD236132102900B723CF980957FC4E177108FC607774F29E8320E92EA05ECE4E821C0A5EFE8F1645C4C0C93C1AB99285D622CAA652C1DFAD63D745D6F2DE5F17E5EAF0FC4963D261C8A12436518206DC093344D5AD293")>]
-[<assembly:System.Runtime.CompilerServices.InternalsVisibleTo("SystematicUnitTests, PublicKey=002400000480000094000000060200000024000052534131000400000100010007D1FA57C4AED9F0A32E84AA0FAEFD0DE9E8FD6AEC8F87FB03766C834C99921EB23BE79AD9D5DCC1DD9AD236132102900B723CF980957FC4E177108FC607774F29E8320E92EA05ECE4E821C0A5EFE8F1645C4C0C93C1AB99285D622CAA652C1DFAD63D745D6F2DE5F17E5EAF0FC4963D261C8A12436518206DC093344D5AD293")>]
+open System.Runtime.CompilerServices
+
+[<assembly:InternalsVisibleTo("FSharp.Build, PublicKey=002400000480000094000000060200000024000052534131000400000100010007D1FA57C4AED9F0A32E84AA0FAEFD0DE9E8FD6AEC8F87FB03766C834C99921EB23BE79AD9D5DCC1DD9AD236132102900B723CF980957FC4E177108FC607774F29E8320E92EA05ECE4E821C0A5EFE8F1645C4C0C93C1AB99285D622CAA652C1DFAD63D745D6F2DE5F17E5EAF0FC4963D261C8A12436518206DC093344D5AD293")>]
+[<assembly:InternalsVisibleTo("FSharp.QuickSearch, PublicKey=002400000480000094000000060200000024000052534131000400000100010007D1FA57C4AED9F0A32E84AA0FAEFD0DE9E8FD6AEC8F87FB03766C834C99921EB23BE79AD9D5DCC1DD9AD236132102900B723CF980957FC4E177108FC607774F29E8320E92EA05ECE4E821C0A5EFE8F1645C4C0C93C1AB99285D622CAA652C1DFAD63D745D6F2DE5F17E5EAF0FC4963D261C8A12436518206DC093344D5AD293")>]
+[<assembly:InternalsVisibleTo("Salsa, PublicKey=002400000480000094000000060200000024000052534131000400000100010007D1FA57C4AED9F0A32E84AA0FAEFD0DE9E8FD6AEC8F87FB03766C834C99921EB23BE79AD9D5DCC1DD9AD236132102900B723CF980957FC4E177108FC607774F29E8320E92EA05ECE4E821C0A5EFE8F1645C4C0C93C1AB99285D622CAA652C1DFAD63D745D6F2DE5F17E5EAF0FC4963D261C8A12436518206DC093344D5AD293")>]
+[<assembly:InternalsVisibleTo("Unittests, PublicKey=002400000480000094000000060200000024000052534131000400000100010007D1FA57C4AED9F0A32E84AA0FAEFD0DE9E8FD6AEC8F87FB03766C834C99921EB23BE79AD9D5DCC1DD9AD236132102900B723CF980957FC4E177108FC607774F29E8320E92EA05ECE4E821C0A5EFE8F1645C4C0C93C1AB99285D622CAA652C1DFAD63D745D6F2DE5F17E5EAF0FC4963D261C8A12436518206DC093344D5AD293")>]
+[<assembly:InternalsVisibleTo("SystematicUnitTests, PublicKey=002400000480000094000000060200000024000052534131000400000100010007D1FA57C4AED9F0A32E84AA0FAEFD0DE9E8FD6AEC8F87FB03766C834C99921EB23BE79AD9D5DCC1DD9AD236132102900B723CF980957FC4E177108FC607774F29E8320E92EA05ECE4E821C0A5EFE8F1645C4C0C93C1AB99285D622CAA652C1DFAD63D745D6F2DE5F17E5EAF0FC4963D261C8A12436518206DC093344D5AD293")>]
+
+// For QA testdrivers and testhooks
+[<assembly:InternalsVisibleTo("Tao.VSLanguages.FSharp, PublicKey=002400000480000094000000060200000024000052534131000400000100010007D1FA57C4AED9F0A32E84AA0FAEFD0DE9E8FD6AEC8F87FB03766C834C99921EB23BE79AD9D5DCC1DD9AD236132102900B723CF980957FC4E177108FC607774F29E8320E92EA05ECE4E821C0A5EFE8F1645C4C0C93C1AB99285D622CAA652C1DFAD63D745D6F2DE5F17E5EAF0FC4963D261C8A12436518206DC093344D5AD293")>]
+[<assembly:InternalsVisibleTo("TNugget, PublicKey=002400000480000094000000060200000024000052534131000400000100010007D1FA57C4AED9F0A32E84AA0FAEFD0DE9E8FD6AEC8F87FB03766C834C99921EB23BE79AD9D5DCC1DD9AD236132102900B723CF980957FC4E177108FC607774F29E8320E92EA05ECE4E821C0A5EFE8F1645C4C0C93C1AB99285D622CAA652C1DFAD63D745D6F2DE5F17E5EAF0FC4963D261C8A12436518206DC093344D5AD293")>]
+
 
 do()
 
diff --git a/vsintegration/src/vs/FsPkgs/FSharp.VS.FSI/InternalsVisibleTo.fs b/vsintegration/src/vs/FsPkgs/FSharp.VS.FSI/InternalsVisibleTo.fs
index 74c8ae3..16c4ffd 100644
--- a/vsintegration/src/vs/FsPkgs/FSharp.VS.FSI/InternalsVisibleTo.fs
+++ b/vsintegration/src/vs/FsPkgs/FSharp.VS.FSI/InternalsVisibleTo.fs
@@ -1,3 +1,5 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
 namespace Microsoft.FSharp
 
 open System.Reflection
diff --git a/vsintegration/src/vs/FsPkgs/FSharp.VS.FSI/VSPackage.resx b/vsintegration/src/vs/FsPkgs/FSharp.VS.FSI/VSPackage.resx
index 2a8b35f..693de5b 100644
--- a/vsintegration/src/vs/FsPkgs/FSharp.VS.FSI/VSPackage.resx
+++ b/vsintegration/src/vs/FsPkgs/FSharp.VS.FSI/VSPackage.resx
@@ -1,4 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information. -->
 <root>
   <!-- 
     Microsoft ResX Schema 
diff --git a/vsintegration/src/vs/FsPkgs/FSharp.VS.FSI/fsiPackageHooks.fs b/vsintegration/src/vs/FsPkgs/FSharp.VS.FSI/fsiPackageHooks.fs
index cb67877..12e82da 100644
--- a/vsintegration/src/vs/FsPkgs/FSharp.VS.FSI/fsiPackageHooks.fs
+++ b/vsintegration/src/vs/FsPkgs/FSharp.VS.FSI/fsiPackageHooks.fs
@@ -1,4 +1,5 @@
-// (c) Microsoft Corporation. All rights reserved
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
 namespace Microsoft.VisualStudio.FSharp.Interactive
 
 open System
diff --git a/vsintegration/src/vs/FsPkgs/common.fs b/vsintegration/src/vs/FsPkgs/common.fs
index d4f54b1..4006cda 100644
--- a/vsintegration/src/vs/FsPkgs/common.fs
+++ b/vsintegration/src/vs/FsPkgs/common.fs
@@ -1,3 +1,5 @@
+// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
+
 namespace Microsoft.VisualStudio.FSharp.Shared
 
     module internal FSharpCommonConstants =

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



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