These are patches cherry-picked from upstream - https://github.com/fsharp/fsharp.git

They are applied inline, rather than as separate patches, so that they
automatically go away once the upstream release containing them is merged in.

See the Debian git history for details
--- fsharp-3.1.1.26+dfsg2.orig/FSharp.PowerPack.Build.Tasks/FSLex.Build.fs
+++ fsharp-3.1.1.26+dfsg2/FSharp.PowerPack.Build.Tasks/FSLex.Build.fs
@@ -1,111 +1,111 @@
-// (c) Microsoft Corporation 2005-2009.
-
-namespace Microsoft.FSharp.Build
-
-open System
-open Microsoft.Build.Framework
-open Microsoft.Build.Utilities
-open Internal.Utilities
-
-(**************************************
-MSBuild task for fslex
-
-options:
-        -o <string>: Name the output file.
-        --codepage <int>: Assume input lexer specification file is encoded with the given codepage.
-        --unicode: Produce a lexer for use with 16-bit unicode characters.
-        --help: display this list of options
-        -help: display this list of options
-**************************************)
-
-type FsLex() = 
-    inherit ToolTask()
-
-    let mutable inputFile  : string = null
-    let mutable outputFile : string = null
-    
-    let mutable codePage   : string = null
-    let mutable unicode   = false
-    let mutable otherFlags   = ""
-
-    let mutable toolPath : string = 
-        match FSharpEnvironment.BinFolderOfFSharpPowerPack with
-        | Some s -> s
-        | None -> ""
-#if FX_ATLEAST_35   
-#else 
-    let mutable toolExe : string = "fslex.exe"
-#endif 
-
-    // [<Required>]
-    member this.InputFile
-        with get ()  = inputFile
-        and  set (x) = inputFile <- x
-    
-    [<Output>]
-    member this.OutputFile
-        with get ()  = outputFile
-        and  set (x) = outputFile <- x
-    
-    // --codepage <int>: Assume input lexer specification file is encoded with the given codepage.
-    member this.CodePage
-        with get ()  = codePage
-        and  set (x) = codePage <- x
-    
-    // --unicode: Produce a lexer for use with 16-bit unicode characters.
-    member this.Unicode
-        with get ()  = unicode
-        and  set (x) = unicode <- x
-
-    member this.OtherFlags
-        with get() = otherFlags
-        and set(s) = otherFlags <- s
-
-    // For targeting other versions of fslex.exe, such as "\LKG\" or "\Prototype\"
-    member this.ToolPath
-        with get ()  = toolPath
-        and  set (s) = toolPath <- s
-        
-#if FX_ATLEAST_35   
-#else 
-    // Name of the .exe to call
-    member this.ToolExe
-        with get ()  = toolExe
-        and  set (s) = toolExe <- s        
-#endif
-
-    // ToolTask methods
-    override this.ToolName = "fslex.exe"
-    
-    override this.GenerateFullPathToTool() = 
-        System.IO.Path.Combine(toolPath, this.ToolExe)
-        
-    override this.GenerateCommandLineCommands() =
-    
-        let builder = new CommandLineBuilder()
-        
-        // CodePage
-        builder.AppendSwitchIfNotNull("--codepage ", codePage)
-        
-        // Unicode
-        if unicode then builder.AppendSwitch("--unicode")
-
-        // OutputFile
-        builder.AppendSwitchIfNotNull("-o ", outputFile)
-
-        // OtherFlags - must be second-to-last
-        builder.AppendSwitchUnquotedIfNotNull("", otherFlags)
-
-        builder.AppendSwitchIfNotNull(" ", inputFile)
-        
-        let args = builder.ToString()
-
-        // when doing simple unit tests using API, no BuildEnginer/Logger is attached
-        if this.BuildEngine <> null then
-            let eventArgs = { new CustomBuildEventArgs(message=args,helpKeyword="",senderName="") with member x.Equals(y) = false }
-            this.BuildEngine.LogCustomEvent(eventArgs)
-        args
-    
-    // Expose this to internal components (for unit testing)
-    member internal this.InternalGenerateCommandLineCommands() =
-        this.GenerateCommandLineCommands()
+// (c) Microsoft Corporation 2005-2009.
+
+namespace Microsoft.FSharp.Build
+
+open System
+open Microsoft.Build.Framework
+open Microsoft.Build.Utilities
+open Internal.Utilities
+
+(**************************************
+MSBuild task for fslex
+
+options:
+        -o <string>: Name the output file.
+        --codepage <int>: Assume input lexer specification file is encoded with the given codepage.
+        --unicode: Produce a lexer for use with 16-bit unicode characters.
+        --help: display this list of options
+        -help: display this list of options
+**************************************)
+
+type FsLex() = 
+    inherit ToolTask()
+
+    let mutable inputFile  : string = null
+    let mutable outputFile : string = null
+    
+    let mutable codePage   : string = null
+    let mutable unicode   = false
+    let mutable otherFlags   = ""
+
+    let mutable toolPath : string = 
+        match FSharpEnvironment.BinFolderOfFSharpPowerPack with
+        | Some s -> s
+        | None -> ""
+#if FX_ATLEAST_35   
+#else 
+    let mutable toolExe : string = "fslex.exe"
+#endif 
+
+    // [<Required>]
+    member this.InputFile
+        with get ()  = inputFile
+        and  set (x) = inputFile <- x
+    
+    [<Output>]
+    member this.OutputFile
+        with get ()  = outputFile
+        and  set (x) = outputFile <- x
+    
+    // --codepage <int>: Assume input lexer specification file is encoded with the given codepage.
+    member this.CodePage
+        with get ()  = codePage
+        and  set (x) = codePage <- x
+    
+    // --unicode: Produce a lexer for use with 16-bit unicode characters.
+    member this.Unicode
+        with get ()  = unicode
+        and  set (x) = unicode <- x
+
+    member this.OtherFlags
+        with get() = otherFlags
+        and set(s) = otherFlags <- s
+
+    // For targeting other versions of fslex.exe, such as "\LKG\" or "\Prototype\"
+    member this.ToolPath
+        with get ()  = toolPath
+        and  set (s) = toolPath <- s
+        
+#if FX_ATLEAST_35   
+#else 
+    // Name of the .exe to call
+    member this.ToolExe
+        with get ()  = toolExe
+        and  set (s) = toolExe <- s        
+#endif
+
+    // ToolTask methods
+    override this.ToolName = "fslex.exe"
+    
+    override this.GenerateFullPathToTool() = 
+        System.IO.Path.Combine(toolPath, this.ToolExe)
+        
+    override this.GenerateCommandLineCommands() =
+    
+        let builder = new CommandLineBuilder()
+        
+        // CodePage
+        builder.AppendSwitchIfNotNull("--codepage ", codePage)
+        
+        // Unicode
+        if unicode then builder.AppendSwitch("--unicode")
+
+        // OutputFile
+        builder.AppendSwitchIfNotNull("-o ", outputFile)
+
+        // OtherFlags - must be second-to-last
+        builder.AppendSwitchUnquotedIfNotNull("", otherFlags)
+
+        builder.AppendSwitchIfNotNull(" ", inputFile)
+        
+        let args = builder.ToString()
+
+        // when doing simple unit tests using API, no BuildEnginer/Logger is attached
+        if this.BuildEngine <> null then
+            let eventArgs = { new CustomBuildEventArgs(message=args,helpKeyword="",senderName="") with member x.Equals(y) = false }
+            this.BuildEngine.LogCustomEvent(eventArgs)
+        args
+    
+    // Expose this to internal components (for unit testing)
+    member internal this.InternalGenerateCommandLineCommands() =
+        this.GenerateCommandLineCommands()
--- fsharp-3.1.1.26+dfsg2.orig/FSharp.PowerPack.Build.Tasks/FSLex.Build.fsi
+++ fsharp-3.1.1.26+dfsg2/FSharp.PowerPack.Build.Tasks/FSLex.Build.fsi
@@ -1,26 +1,26 @@
-// (c) Microsoft Corporation 2005-2009.
-
-namespace Microsoft.FSharp.Build
-
-type FsLex =
-    inherit Microsoft.Build.Utilities.ToolTask
-
-    new : unit -> FsLex
-    
-    override GenerateCommandLineCommands : unit -> System.String
-    override GenerateFullPathToTool : unit -> System.String
-    override ToolName : System.String
-    
-    member internal InternalGenerateCommandLineCommands : unit -> System.String
-    
-    member InputFile  : string with set
-    [<Microsoft.Build.Framework.Output>]
-    member OutputFile : string with set
-    member CodePage   : string with set
-    member OtherFlags : string with set
-    member Unicode    : bool   with set
-    member ToolPath   : string with set
-#if FX_ATLEAST_35   
-#else 
-    member ToolExe    : string with set    
+// (c) Microsoft Corporation 2005-2009.
+
+namespace Microsoft.FSharp.Build
+
+type FsLex =
+    inherit Microsoft.Build.Utilities.ToolTask
+
+    new : unit -> FsLex
+    
+    override GenerateCommandLineCommands : unit -> System.String
+    override GenerateFullPathToTool : unit -> System.String
+    override ToolName : System.String
+    
+    member internal InternalGenerateCommandLineCommands : unit -> System.String
+    
+    member InputFile  : string with set
+    [<Microsoft.Build.Framework.Output>]
+    member OutputFile : string with set
+    member CodePage   : string with set
+    member OtherFlags : string with set
+    member Unicode    : bool   with set
+    member ToolPath   : string with set
+#if FX_ATLEAST_35   
+#else 
+    member ToolExe    : string with set    
 #endif
\ No newline at end of file
--- fsharp-3.1.1.26+dfsg2.orig/FSharp.PowerPack.Build.Tasks/FSYacc.Build.fs
+++ fsharp-3.1.1.26+dfsg2/FSharp.PowerPack.Build.Tasks/FSYacc.Build.fs
@@ -1,124 +1,124 @@
-// (c) Microsoft Corporation 2005-2009.
-
-namespace Microsoft.FSharp.Build
-
-open System
-open Microsoft.Build.Framework
-open Microsoft.Build.Utilities
-open Internal.Utilities
-
-(**************************************
-MSBuild task for fsyacc
-**************************************)
-
-type FsYacc() = 
-    inherit ToolTask()
-
-    let mutable inputFile  : string = null
-    let mutable outputFile : string = null
-    
-    let mutable codePage   : string = null
-    let mutable otherFlags : string = null
-    let mutable mlCompat   = false
-    
-    let mutable _open  : string = null
-    let mutable _module  : string = null
-
-    let mutable toolPath : string = 
-        match FSharpEnvironment.BinFolderOfFSharpPowerPack with
-        | Some s -> s
-        | None -> ""
-#if FX_ATLEAST_35
-#else
-    let mutable toolExe : string = "fsyacc.exe"
-#endif
-
-    // [<Required>]
-    member this.InputFile
-        with get ()  = inputFile
-        and  set (x) = inputFile <- x
-    
-    [<Microsoft.Build.Framework.Output>]
-    member this.OutputFile
-        with get ()  = outputFile
-        and  set (x) = outputFile <- x
-    
-    member this.OtherFlags
-        with get() = otherFlags
-        and set(s) = otherFlags <- s
-
-    // --codepage <int>: Assume input lexer specification file is encoded with the given codepage.
-    member this.CodePage
-        with get ()  = codePage
-        and  set (x) = codePage <- x
-    
-    // --ml-compatibility: Support the use of the global state from the 'Parsing' module in MLLib.
-    member this.MLCompatibility
-        with get ()  = mlCompat
-        and  set (x) = mlCompat <- x
-        
-    // --open
-    member this.Open
-        with get ()  = _open
-        and  set (x) = _open <- x       
-
-   // --module
-    member this.Module
-        with get ()  = _module
-        and  set (x) = _module <- x             
-
-    // For targeting other versions of fslex.exe, such as "\LKG\" or "\Prototype\"
-    member this.ToolPath
-        with get ()  = toolPath
-        and  set (s) = toolPath <- s
-        
-#if FX_ATLEAST_35
-#else
-    // Name of the .exe to call
-    member this.ToolExe
-        with get ()  = toolExe
-        and  set (s) = toolExe <- s        
-#endif
-
-    // ToolTask methods
-    override this.ToolName = "fsyacc.exe"
-    
-    override this.GenerateFullPathToTool() = 
-        System.IO.Path.Combine(toolPath, this.ToolExe)
-        
-    override this.GenerateCommandLineCommands() =
-    
-        let builder = new CommandLineBuilder()
-        
-        // CodePage
-        builder.AppendSwitchIfNotNull("--codepage ", codePage)
-        
-        // ML Compatibility
-        if mlCompat then builder.AppendSwitch("--ml-compatibility")
-
-        // Open
-        builder.AppendSwitchIfNotNull("--open ", _open)
-
-        // Module
-        builder.AppendSwitchIfNotNull("--module ", _module)
-
-        // OutputFile
-        builder.AppendSwitchIfNotNull("-o ", outputFile)
-
-        // OtherFlags - must be second-to-last
-        builder.AppendSwitchUnquotedIfNotNull("", otherFlags)
-
-        builder.AppendSwitchIfNotNull(" ", inputFile)
-        
-        let args = builder.ToString()
-
-        // when doing simple unit tests using API, no BuildEnginer/Logger is attached
-        if this.BuildEngine <> null then
-            let eventArgs = { new CustomBuildEventArgs(message=args,helpKeyword="",senderName="") with member x.Equals(y) = false }
-            this.BuildEngine.LogCustomEvent(eventArgs)
-        
-        args
-    
-    // Expose this to internal components (for unit testing)
-    member internal this.InternalGenerateCommandLineCommands() =
-        this.GenerateCommandLineCommands()
+// (c) Microsoft Corporation 2005-2009.
+
+namespace Microsoft.FSharp.Build
+
+open System
+open Microsoft.Build.Framework
+open Microsoft.Build.Utilities
+open Internal.Utilities
+
+(**************************************
+MSBuild task for fsyacc
+**************************************)
+
+type FsYacc() = 
+    inherit ToolTask()
+
+    let mutable inputFile  : string = null
+    let mutable outputFile : string = null
+    
+    let mutable codePage   : string = null
+    let mutable otherFlags : string = null
+    let mutable mlCompat   = false
+    
+    let mutable _open  : string = null
+    let mutable _module  : string = null
+
+    let mutable toolPath : string = 
+        match FSharpEnvironment.BinFolderOfFSharpPowerPack with
+        | Some s -> s
+        | None -> ""
+#if FX_ATLEAST_35
+#else
+    let mutable toolExe : string = "fsyacc.exe"
+#endif
+
+    // [<Required>]
+    member this.InputFile
+        with get ()  = inputFile
+        and  set (x) = inputFile <- x
+    
+    [<Microsoft.Build.Framework.Output>]
+    member this.OutputFile
+        with get ()  = outputFile
+        and  set (x) = outputFile <- x
+    
+    member this.OtherFlags
+        with get() = otherFlags
+        and set(s) = otherFlags <- s
+
+    // --codepage <int>: Assume input lexer specification file is encoded with the given codepage.
+    member this.CodePage
+        with get ()  = codePage
+        and  set (x) = codePage <- x
+    
+    // --ml-compatibility: Support the use of the global state from the 'Parsing' module in MLLib.
+    member this.MLCompatibility
+        with get ()  = mlCompat
+        and  set (x) = mlCompat <- x
+        
+    // --open
+    member this.Open
+        with get ()  = _open
+        and  set (x) = _open <- x       
+
+   // --module
+    member this.Module
+        with get ()  = _module
+        and  set (x) = _module <- x             
+
+    // For targeting other versions of fslex.exe, such as "\LKG\" or "\Prototype\"
+    member this.ToolPath
+        with get ()  = toolPath
+        and  set (s) = toolPath <- s
+        
+#if FX_ATLEAST_35
+#else
+    // Name of the .exe to call
+    member this.ToolExe
+        with get ()  = toolExe
+        and  set (s) = toolExe <- s        
+#endif
+
+    // ToolTask methods
+    override this.ToolName = "fsyacc.exe"
+    
+    override this.GenerateFullPathToTool() = 
+        System.IO.Path.Combine(toolPath, this.ToolExe)
+        
+    override this.GenerateCommandLineCommands() =
+    
+        let builder = new CommandLineBuilder()
+        
+        // CodePage
+        builder.AppendSwitchIfNotNull("--codepage ", codePage)
+        
+        // ML Compatibility
+        if mlCompat then builder.AppendSwitch("--ml-compatibility")
+
+        // Open
+        builder.AppendSwitchIfNotNull("--open ", _open)
+
+        // Module
+        builder.AppendSwitchIfNotNull("--module ", _module)
+
+        // OutputFile
+        builder.AppendSwitchIfNotNull("-o ", outputFile)
+
+        // OtherFlags - must be second-to-last
+        builder.AppendSwitchUnquotedIfNotNull("", otherFlags)
+
+        builder.AppendSwitchIfNotNull(" ", inputFile)
+        
+        let args = builder.ToString()
+
+        // when doing simple unit tests using API, no BuildEnginer/Logger is attached
+        if this.BuildEngine <> null then
+            let eventArgs = { new CustomBuildEventArgs(message=args,helpKeyword="",senderName="") with member x.Equals(y) = false }
+            this.BuildEngine.LogCustomEvent(eventArgs)
+        
+        args
+    
+    // Expose this to internal components (for unit testing)
+    member internal this.InternalGenerateCommandLineCommands() =
+        this.GenerateCommandLineCommands()
--- fsharp-3.1.1.26+dfsg2.orig/FSharp.PowerPack.Build.Tasks/FSYacc.Build.fsi
+++ fsharp-3.1.1.26+dfsg2/FSharp.PowerPack.Build.Tasks/FSYacc.Build.fsi
@@ -1,28 +1,28 @@
-// (c) Microsoft Corporation 2005-2009.
-
-namespace Microsoft.FSharp.Build
-
-type FsYacc =
-    inherit Microsoft.Build.Utilities.ToolTask
-
-    new : unit -> FsYacc
-    
-    override GenerateCommandLineCommands : unit -> System.String
-    override GenerateFullPathToTool : unit -> System.String
-    override ToolName : System.String
-    
-    member internal InternalGenerateCommandLineCommands : unit -> System.String
-    
-    member InputFile  : string with set
-    [<Microsoft.Build.Framework.Output>]
-    member OutputFile : string with set
-    member CodePage   : string with set
-    member OtherFlags : string with set
-    member MLCompatibility : bool with set
-    member Open : string with set
-    member Module   : string with set
-    member ToolPath   : string with set
-#if FX_ATLEAST_35
-#else
-    member ToolExe   : string with set    
+// (c) Microsoft Corporation 2005-2009.
+
+namespace Microsoft.FSharp.Build
+
+type FsYacc =
+    inherit Microsoft.Build.Utilities.ToolTask
+
+    new : unit -> FsYacc
+    
+    override GenerateCommandLineCommands : unit -> System.String
+    override GenerateFullPathToTool : unit -> System.String
+    override ToolName : System.String
+    
+    member internal InternalGenerateCommandLineCommands : unit -> System.String
+    
+    member InputFile  : string with set
+    [<Microsoft.Build.Framework.Output>]
+    member OutputFile : string with set
+    member CodePage   : string with set
+    member OtherFlags : string with set
+    member MLCompatibility : bool with set
+    member Open : string with set
+    member Module   : string with set
+    member ToolPath   : string with set
+#if FX_ATLEAST_35
+#else
+    member ToolExe   : string with set    
 #endif
\ No newline at end of file
--- fsharp-3.1.1.26+dfsg2.orig/FSharp.PowerPack.Build.Tasks/FSharp.PowerPack.Build.Tasks.fsproj.vspscc
+++ fsharp-3.1.1.26+dfsg2/FSharp.PowerPack.Build.Tasks/FSharp.PowerPack.Build.Tasks.fsproj.vspscc
@@ -1,10 +1,10 @@
-﻿""
-{
-"FILE_VERSION" = "9237"
-"ENLISTMENT_CHOICE" = "NEVER"
-"PROJECT_FILE_RELATIVE_PATH" = ""
-"NUMBER_OF_EXCLUDED_FILES" = "0"
-"ORIGINAL_PROJECT_FILE_PATH" = ""
-"NUMBER_OF_NESTED_PROJECTS" = "0"
-"SOURCE_CONTROL_SETTINGS_PROVIDER" = "PROVIDER"
-}
+﻿""
+{
+"FILE_VERSION" = "9237"
+"ENLISTMENT_CHOICE" = "NEVER"
+"PROJECT_FILE_RELATIVE_PATH" = ""
+"NUMBER_OF_EXCLUDED_FILES" = "0"
+"ORIGINAL_PROJECT_FILE_PATH" = ""
+"NUMBER_OF_NESTED_PROJECTS" = "0"
+"SOURCE_CONTROL_SETTINGS_PROVIDER" = "PROVIDER"
+}
--- fsharp-3.1.1.26+dfsg2.orig/FSharp.PowerPack.Build.Tasks/FSharp.PowerPack.targets
+++ fsharp-3.1.1.26+dfsg2/FSharp.PowerPack.Build.Tasks/FSharp.PowerPack.targets
@@ -1,84 +1,84 @@
-<!--
-***********************************************************************************************
-FSharp.PowerPack.targets
-
-WARNING:  DO NOT MODIFY this file unless you are knowledgeable about MSBuild and have
-		  created a backup copy.  Incorrect changes to this file will make it
-		  impossible to load or build your projects from the command-line or the IDE.
-
-PowerPack build rules.
-
-Copyright (C) Microsoft Corporation. All rights reserved.
-***********************************************************************************************
--->
-
-<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-	<UsingTask TaskName="FsLex" AssemblyFile="FSharp.PowerPack.Build.Tasks.dll"/>
-	<UsingTask TaskName="FsYacc" AssemblyFile="FSharp.PowerPack.Build.Tasks.dll"/>
-	<PropertyGroup>
-		<CompileDependsOn>CallFsLex;CallFsYacc;$(CompileDependsOn)</CompileDependsOn>
-	</PropertyGroup>
-
-	<!-- Build FsLex files. -->
-	<Target
-		Name="CallFsLex"
-		Inputs="@(FsLex)"
-		Outputs="@(FsLex->'$(FsLexOutputFolder)%(Filename).fs')"
-		Condition="'@(FsLex)'!=''">
-
-		<!-- Create the output directory -->
-		<MakeDir Directories="$(FsLexOutputFolder)"/>
-		<!-- Call FsLex -->
-		<FsLex
-			InputFile="%(FsLex.Identity)"
-			OutputFile="$(FsLexOutputFolder)%(FsLex.Filename).fs"
-			ToolPath="$(FsLexToolPath)"
-			ToolExe="$(FsLexToolExe)"
-			OtherFlags="%(FsLex.OtherFlags)"
-			Unicode="$(FsLexUnicode)">
-			<!-- Track outputs for 'Clean' -->
-			<Output TaskParameter="OutputFile" ItemName="FileWrites"/>
-		</FsLex>
-    <!-- Make sure it will get cleaned  -->
-    <CreateItem Include="$(FsLexOutputFolder)%(FsLex.Filename).fs">
-      <Output TaskParameter="Include" ItemName="FileWrites"/>
-    </CreateItem>
-  </Target>
-
-	<!-- Build FsYacc files. -->
-	<Target
-		Name="CallFsYacc"
-		Inputs="@(FsYacc)"
-		Outputs="@(FsYacc->'$(FsYaccOutputFolder)%(Filename).fs')"
-		Condition="'@(FsYacc)'!=''">
-
-		<!-- Create the output directory -->
-		<MakeDir Directories="$(FsYaccOutputFolder)"/>
-		<!-- Call FsYacc -->
-		<FsYacc
-			InputFile="%(FsYacc.Identity)"
-			OutputFile="$(FsYaccOutputFolder)%(FsYacc.Filename).fs"
-			Open="%(FsYacc.Open)"
-			Module="%(FsYacc.Module)"
-			OtherFlags="%(FsYacc.OtherFlags)"
-			ToolPath="$(FsYaccToolPath)"
-			ToolExe="$(FsYaccToolExe)">
-			<!-- Track outputs for 'Clean' -->
-			<Output TaskParameter="OutputFile" ItemName="FileWrites"/>
-    </FsYacc>
-    <!-- Make sure it will get cleaned  -->
-    <CreateItem Include="$(FsYaccOutputFolder)%(FsYacc.Filename).fs">
-      <Output TaskParameter="Include" ItemName="FileWrites"/>
-    </CreateItem>
-  </Target>
-	<ItemGroup>
-       <AvailableItemName Include="FsLex">
-           <Visible>false</Visible>
-       </AvailableItemName>
-       <AvailableItemName Include="FsYacc">
-           <Visible>false</Visible>
-       </AvailableItemName>
-    </ItemGroup>
-</Project>
-
-
+<!--
+***********************************************************************************************
+FSharp.PowerPack.targets
+
+WARNING:  DO NOT MODIFY this file unless you are knowledgeable about MSBuild and have
+		  created a backup copy.  Incorrect changes to this file will make it
+		  impossible to load or build your projects from the command-line or the IDE.
+
+PowerPack build rules.
+
+Copyright (C) Microsoft Corporation. All rights reserved.
+***********************************************************************************************
+-->
+
+<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+	<UsingTask TaskName="FsLex" AssemblyFile="FSharp.PowerPack.Build.Tasks.dll"/>
+	<UsingTask TaskName="FsYacc" AssemblyFile="FSharp.PowerPack.Build.Tasks.dll"/>
+	<PropertyGroup>
+		<CompileDependsOn>CallFsLex;CallFsYacc;$(CompileDependsOn)</CompileDependsOn>
+	</PropertyGroup>
+
+	<!-- Build FsLex files. -->
+	<Target
+		Name="CallFsLex"
+		Inputs="@(FsLex)"
+		Outputs="@(FsLex->'$(FsLexOutputFolder)%(Filename).fs')"
+		Condition="'@(FsLex)'!=''">
+
+		<!-- Create the output directory -->
+		<MakeDir Directories="$(FsLexOutputFolder)"/>
+		<!-- Call FsLex -->
+		<FsLex
+			InputFile="%(FsLex.Identity)"
+			OutputFile="$(FsLexOutputFolder)%(FsLex.Filename).fs"
+			ToolPath="$(FsLexToolPath)"
+			ToolExe="$(FsLexToolExe)"
+			OtherFlags="%(FsLex.OtherFlags)"
+			Unicode="$(FsLexUnicode)">
+			<!-- Track outputs for 'Clean' -->
+			<Output TaskParameter="OutputFile" ItemName="FileWrites"/>
+		</FsLex>
+    <!-- Make sure it will get cleaned  -->
+    <CreateItem Include="$(FsLexOutputFolder)%(FsLex.Filename).fs">
+      <Output TaskParameter="Include" ItemName="FileWrites"/>
+    </CreateItem>
+  </Target>
+
+	<!-- Build FsYacc files. -->
+	<Target
+		Name="CallFsYacc"
+		Inputs="@(FsYacc)"
+		Outputs="@(FsYacc->'$(FsYaccOutputFolder)%(Filename).fs')"
+		Condition="'@(FsYacc)'!=''">
+
+		<!-- Create the output directory -->
+		<MakeDir Directories="$(FsYaccOutputFolder)"/>
+		<!-- Call FsYacc -->
+		<FsYacc
+			InputFile="%(FsYacc.Identity)"
+			OutputFile="$(FsYaccOutputFolder)%(FsYacc.Filename).fs"
+			Open="%(FsYacc.Open)"
+			Module="%(FsYacc.Module)"
+			OtherFlags="%(FsYacc.OtherFlags)"
+			ToolPath="$(FsYaccToolPath)"
+			ToolExe="$(FsYaccToolExe)">
+			<!-- Track outputs for 'Clean' -->
+			<Output TaskParameter="OutputFile" ItemName="FileWrites"/>
+    </FsYacc>
+    <!-- Make sure it will get cleaned  -->
+    <CreateItem Include="$(FsYaccOutputFolder)%(FsYacc.Filename).fs">
+      <Output TaskParameter="Include" ItemName="FileWrites"/>
+    </CreateItem>
+  </Target>
+	<ItemGroup>
+       <AvailableItemName Include="FsLex">
+           <Visible>false</Visible>
+       </AvailableItemName>
+       <AvailableItemName Include="FsYacc">
+           <Visible>false</Visible>
+       </AvailableItemName>
+    </ItemGroup>
+</Project>
+
+
--- fsharp-3.1.1.26+dfsg2.orig/FSharp.PowerPack.Build.Tasks/assemblyinfo.FSharp.PowerPack.Build.Tasks.dll.fs
+++ fsharp-3.1.1.26+dfsg2/FSharp.PowerPack.Build.Tasks/assemblyinfo.FSharp.PowerPack.Build.Tasks.dll.fs
@@ -1,7 +1,7 @@
-namespace Microsoft.FSharp
-open System.Reflection
-[<assembly:AssemblyDescription("FSharp.PowerPack.Build.Tasks.dll")>]
-[<assembly:AssemblyCompany("F# PowerPack CodePlex Project")>]
-[<assembly:AssemblyTitle("FSharp.PowerPack.Build.Tasks.dll")>]
-[<assembly:AssemblyProduct("F# Power Pack")>]
-do()
+namespace Microsoft.FSharp
+open System.Reflection
+[<assembly:AssemblyDescription("FSharp.PowerPack.Build.Tasks.dll")>]
+[<assembly:AssemblyCompany("F# PowerPack CodePlex Project")>]
+[<assembly:AssemblyTitle("FSharp.PowerPack.Build.Tasks.dll")>]
+[<assembly:AssemblyProduct("F# Power Pack")>]
+do()
--- fsharp-3.1.1.26+dfsg2.orig/FSharp.PowerPack/Arg.fs
+++ fsharp-3.1.1.26+dfsg2/FSharp.PowerPack/Arg.fs
@@ -1,133 +1,133 @@
-// (c) Microsoft Corporation 2005-2009. 
-
-#if INTERNALIZED_POWER_PACK
-namespace Internal.Utilities
-#else
-namespace Microsoft.FSharp.Text
-#endif
-
-
-type ArgType = 
-  | ClearArg of bool ref
-  | FloatArg of (float -> unit)
-  | IntArg of (int -> unit)
-  | RestArg of (string -> unit)
-  | SetArg of bool ref
-  | StringArg of (string -> unit)
-  | UnitArg of (unit -> unit)
-  static member Clear  r = ClearArg r
-  static member Float  r = FloatArg r
-  static member Int    r = IntArg r
-  static member Rest   r = RestArg r
-  static member Set    r = SetArg r
-  static member String r = StringArg r
-  static member Unit   r = UnitArg r
-
-
-type ArgInfo (name,action,help) = 
-  member x.Name = name
-  member x.ArgType = action
-  member x.HelpText = help
-  
-exception Bad of string
-exception HelpText of string
-
-[<Sealed>]
-type ArgParser() = 
-    static let getUsage specs u =  
-      let sbuf = new System.Text.StringBuilder 100  
-      let pstring (s:string) = sbuf.Append s |> ignore 
-      let pendline s = pstring s; pstring "\n" 
-      pendline u;
-      List.iter (fun (arg:ArgInfo) -> 
-        match arg.Name, arg.ArgType, arg.HelpText with
-        | (s, (UnitArg _ | SetArg _ | ClearArg _), helpText) -> pstring "\t"; pstring s; pstring ": "; pendline helpText
-        | (s, StringArg _, helpText) -> pstring "\t"; pstring s; pstring " <string>: "; pendline helpText
-        | (s, IntArg _, helpText) -> pstring "\t"; pstring s; pstring " <int>: "; pendline helpText
-        | (s, FloatArg _, helpText) ->  pstring "\t"; pstring s; pstring " <float>: "; pendline helpText
-        | (s, RestArg _, helpText) -> pstring "\t"; pstring s; pstring " ...: "; pendline helpText)
-        specs;
-      pstring "\t"; pstring "--help"; pstring ": "; pendline "display this list of options";
-      pstring "\t"; pstring "-help"; pstring ": "; pendline "display this list of options";
-      sbuf.ToString()
-
-
-    static member ParsePartial(cursor,argv,argSpecs:seq<ArgInfo>,?other,?usageText) =
-        let other = defaultArg other (fun _ -> ())
-        let usageText = defaultArg usageText ""
-        let nargs = Array.length argv 
-        incr cursor;
-        let argSpecs = argSpecs |> Seq.toList
-        let specs = argSpecs |> List.map (fun (arg:ArgInfo) -> arg.Name, arg.ArgType)
-        while !cursor < nargs do
-          let arg = argv.[!cursor] 
-          let rec findMatchingArg args = 
-            match args with
-            | ((s, action) :: _) when s = arg -> 
-               let getSecondArg () = 
-                   if !cursor + 1 >= nargs then 
-                     raise(Bad("option "+s+" needs an argument.\n"+getUsage argSpecs usageText));
-                   argv.[!cursor+1] 
-                 
-               match action with 
-               | UnitArg f -> 
-                 f (); 
-                 incr cursor
-               | SetArg f ->
-                 f := true; 
-                 incr cursor
-               | ClearArg f -> 
-                 f := false; 
-                 incr cursor
-               | StringArg f-> 
-                 let arg2 = getSecondArg() 
-                 f arg2; 
-                 cursor := !cursor + 2
-               | IntArg f -> 
-                 let arg2 = getSecondArg () 
-                 let arg2 = try int32 arg2 with _ -> raise(Bad(getUsage argSpecs usageText)) in  
-                 f arg2;
-                 cursor := !cursor + 2;
-               | FloatArg f -> 
-                 let arg2 = getSecondArg() 
-                 let arg2 = try float arg2 with _ -> raise(Bad(getUsage argSpecs usageText)) in 
-                 f arg2; 
-                 cursor := !cursor + 2;
-               | RestArg f -> 
-                 incr cursor;
-                 while !cursor < nargs do
-                     f (argv.[!cursor]);
-                     incr cursor;
-
-            | (_ :: more)  -> findMatchingArg more 
-            | [] -> 
-                if arg = "-help" || arg = "--help" || arg = "/help" || arg = "/help" || arg = "/?" then
-                    raise (HelpText (getUsage argSpecs usageText))
-                // Note: for '/abc/def' does not count as an argument
-                // Note: '/abc' does
-                elif arg.Length>0 && (arg.[0] = '-' || (arg.[0] = '/' && not (arg.Length > 1 && arg.[1..].Contains ("/")))) then
-                    raise (Bad ("unrecognized argument: "+ arg + "\n" + getUsage argSpecs usageText))
-                else 
-                   other arg;
-                   incr cursor
-          findMatchingArg specs 
-
-    static member Usage (specs,?usage) = 
-        let usage = defaultArg usage ""
-        System.Console.Error.WriteLine (getUsage (Seq.toList specs) usage)
-
-    #if FX_NO_COMMAND_LINE_ARGS
-    #else
-    static member Parse (specs,?other,?usageText) = 
-        let current = ref 0
-        let argv = System.Environment.GetCommandLineArgs() 
-        try ArgParser.ParsePartial (current, argv, specs, ?other=other, ?usageText=usageText)
-        with 
-          | Bad h 
-          | HelpText h -> 
-              System.Console.Error.WriteLine h; 
-              System.Console.Error.Flush();  
-              System.Environment.Exit(1); 
-          | e -> 
-              reraise()
-    #endif
+// (c) Microsoft Corporation 2005-2009. 
+
+#if INTERNALIZED_POWER_PACK
+namespace Internal.Utilities
+#else
+namespace Microsoft.FSharp.Text
+#endif
+
+
+type ArgType = 
+  | ClearArg of bool ref
+  | FloatArg of (float -> unit)
+  | IntArg of (int -> unit)
+  | RestArg of (string -> unit)
+  | SetArg of bool ref
+  | StringArg of (string -> unit)
+  | UnitArg of (unit -> unit)
+  static member Clear  r = ClearArg r
+  static member Float  r = FloatArg r
+  static member Int    r = IntArg r
+  static member Rest   r = RestArg r
+  static member Set    r = SetArg r
+  static member String r = StringArg r
+  static member Unit   r = UnitArg r
+
+
+type ArgInfo (name,action,help) = 
+  member x.Name = name
+  member x.ArgType = action
+  member x.HelpText = help
+  
+exception Bad of string
+exception HelpText of string
+
+[<Sealed>]
+type ArgParser() = 
+    static let getUsage specs u =  
+      let sbuf = new System.Text.StringBuilder 100  
+      let pstring (s:string) = sbuf.Append s |> ignore 
+      let pendline s = pstring s; pstring "\n" 
+      pendline u;
+      List.iter (fun (arg:ArgInfo) -> 
+        match arg.Name, arg.ArgType, arg.HelpText with
+        | (s, (UnitArg _ | SetArg _ | ClearArg _), helpText) -> pstring "\t"; pstring s; pstring ": "; pendline helpText
+        | (s, StringArg _, helpText) -> pstring "\t"; pstring s; pstring " <string>: "; pendline helpText
+        | (s, IntArg _, helpText) -> pstring "\t"; pstring s; pstring " <int>: "; pendline helpText
+        | (s, FloatArg _, helpText) ->  pstring "\t"; pstring s; pstring " <float>: "; pendline helpText
+        | (s, RestArg _, helpText) -> pstring "\t"; pstring s; pstring " ...: "; pendline helpText)
+        specs;
+      pstring "\t"; pstring "--help"; pstring ": "; pendline "display this list of options";
+      pstring "\t"; pstring "-help"; pstring ": "; pendline "display this list of options";
+      sbuf.ToString()
+
+
+    static member ParsePartial(cursor,argv,argSpecs:seq<ArgInfo>,?other,?usageText) =
+        let other = defaultArg other (fun _ -> ())
+        let usageText = defaultArg usageText ""
+        let nargs = Array.length argv 
+        incr cursor;
+        let argSpecs = argSpecs |> Seq.toList
+        let specs = argSpecs |> List.map (fun (arg:ArgInfo) -> arg.Name, arg.ArgType)
+        while !cursor < nargs do
+          let arg = argv.[!cursor] 
+          let rec findMatchingArg args = 
+            match args with
+            | ((s, action) :: _) when s = arg -> 
+               let getSecondArg () = 
+                   if !cursor + 1 >= nargs then 
+                     raise(Bad("option "+s+" needs an argument.\n"+getUsage argSpecs usageText));
+                   argv.[!cursor+1] 
+                 
+               match action with 
+               | UnitArg f -> 
+                 f (); 
+                 incr cursor
+               | SetArg f ->
+                 f := true; 
+                 incr cursor
+               | ClearArg f -> 
+                 f := false; 
+                 incr cursor
+               | StringArg f-> 
+                 let arg2 = getSecondArg() 
+                 f arg2; 
+                 cursor := !cursor + 2
+               | IntArg f -> 
+                 let arg2 = getSecondArg () 
+                 let arg2 = try int32 arg2 with _ -> raise(Bad(getUsage argSpecs usageText)) in  
+                 f arg2;
+                 cursor := !cursor + 2;
+               | FloatArg f -> 
+                 let arg2 = getSecondArg() 
+                 let arg2 = try float arg2 with _ -> raise(Bad(getUsage argSpecs usageText)) in 
+                 f arg2; 
+                 cursor := !cursor + 2;
+               | RestArg f -> 
+                 incr cursor;
+                 while !cursor < nargs do
+                     f (argv.[!cursor]);
+                     incr cursor;
+
+            | (_ :: more)  -> findMatchingArg more 
+            | [] -> 
+                if arg = "-help" || arg = "--help" || arg = "/help" || arg = "/help" || arg = "/?" then
+                    raise (HelpText (getUsage argSpecs usageText))
+                // Note: for '/abc/def' does not count as an argument
+                // Note: '/abc' does
+                elif arg.Length>0 && (arg.[0] = '-' || (arg.[0] = '/' && not (arg.Length > 1 && arg.[1..].Contains ("/")))) then
+                    raise (Bad ("unrecognized argument: "+ arg + "\n" + getUsage argSpecs usageText))
+                else 
+                   other arg;
+                   incr cursor
+          findMatchingArg specs 
+
+    static member Usage (specs,?usage) = 
+        let usage = defaultArg usage ""
+        System.Console.Error.WriteLine (getUsage (Seq.toList specs) usage)
+
+    #if FX_NO_COMMAND_LINE_ARGS
+    #else
+    static member Parse (specs,?other,?usageText) = 
+        let current = ref 0
+        let argv = System.Environment.GetCommandLineArgs() 
+        try ArgParser.ParsePartial (current, argv, specs, ?other=other, ?usageText=usageText)
+        with 
+          | Bad h 
+          | HelpText h -> 
+              System.Console.Error.WriteLine h; 
+              System.Console.Error.Flush();  
+              System.Environment.Exit(1); 
+          | e -> 
+              reraise()
+    #endif
--- fsharp-3.1.1.26+dfsg2.orig/FSharp.PowerPack/Arg.fsi
+++ fsharp-3.1.1.26+dfsg2/FSharp.PowerPack/Arg.fsi
@@ -1,50 +1,50 @@
-// (c) Microsoft Corporation 2005-2009. 
-
-/// A simple command-line argument processor.
-#if INTERNALIZED_POWER_PACK
-namespace Internal.Utilities
-#else
-namespace Microsoft.FSharp.Text
-#endif
-
-/// The spec value describes the action of the argument,
-/// and whether it expects a following parameter.
-[<Sealed>]
-type ArgType = 
-    static member Clear  : bool ref         -> ArgType
-    static member Float  : (float -> unit)  -> ArgType
-    static member Int    : (int -> unit)    -> ArgType
-    static member Rest   : (string -> unit) -> ArgType
-    static member Set    : bool ref         -> ArgType
-    static member String : (string -> unit) -> ArgType
-    static member Unit   : (unit -> unit)   -> ArgType
-
-type ArgInfo = 
-  new : name:string * action:ArgType * help:string -> ArgInfo
-  /// Return the name of the argument
-  member Name : string
-  /// Return the argument type and action of the argument
-  member ArgType : ArgType
-  /// Return the usage help associated with the argument
-  member HelpText : string
-
-[<Sealed>]
-type ArgParser = 
-    #if FX_NO_COMMAND_LINE_ARGS
-    #else
-
-    /// Parse some of the arguments given by 'argv', starting at the given position
-    [<System.Obsolete("This method should not be used directly as it will be removed in a future revision of this library")>]
-    static member ParsePartial: cursor: int ref * argv: string[] * arguments:seq<ArgInfo> * ?otherArgs: (string -> unit) * ?usageText:string -> unit
-
-    /// Parse the arguments given by System.Environment.GetEnvironmentVariables()
-    /// according to the argument processing specifications "specs".
-    /// Args begin with "-". Non-arguments are passed to "f" in
-    /// order.  "use" is printed as part of the usage line if an error occurs.
-
-    static member Parse: arguments:seq<ArgInfo> * ?otherArgs: (string -> unit) * ?usageText:string -> unit
-    #endif
-
-    /// Prints the help for each argument.
-    static member Usage : arguments:seq<ArgInfo> * ?usage:string -> unit
-
+// (c) Microsoft Corporation 2005-2009. 
+
+/// A simple command-line argument processor.
+#if INTERNALIZED_POWER_PACK
+namespace Internal.Utilities
+#else
+namespace Microsoft.FSharp.Text
+#endif
+
+/// The spec value describes the action of the argument,
+/// and whether it expects a following parameter.
+[<Sealed>]
+type ArgType = 
+    static member Clear  : bool ref         -> ArgType
+    static member Float  : (float -> unit)  -> ArgType
+    static member Int    : (int -> unit)    -> ArgType
+    static member Rest   : (string -> unit) -> ArgType
+    static member Set    : bool ref         -> ArgType
+    static member String : (string -> unit) -> ArgType
+    static member Unit   : (unit -> unit)   -> ArgType
+
+type ArgInfo = 
+  new : name:string * action:ArgType * help:string -> ArgInfo
+  /// Return the name of the argument
+  member Name : string
+  /// Return the argument type and action of the argument
+  member ArgType : ArgType
+  /// Return the usage help associated with the argument
+  member HelpText : string
+
+[<Sealed>]
+type ArgParser = 
+    #if FX_NO_COMMAND_LINE_ARGS
+    #else
+
+    /// Parse some of the arguments given by 'argv', starting at the given position
+    [<System.Obsolete("This method should not be used directly as it will be removed in a future revision of this library")>]
+    static member ParsePartial: cursor: int ref * argv: string[] * arguments:seq<ArgInfo> * ?otherArgs: (string -> unit) * ?usageText:string -> unit
+
+    /// Parse the arguments given by System.Environment.GetEnvironmentVariables()
+    /// according to the argument processing specifications "specs".
+    /// Args begin with "-". Non-arguments are passed to "f" in
+    /// order.  "use" is printed as part of the usage line if an error occurs.
+
+    static member Parse: arguments:seq<ArgInfo> * ?otherArgs: (string -> unit) * ?usageText:string -> unit
+    #endif
+
+    /// Prints the help for each argument.
+    static member Usage : arguments:seq<ArgInfo> * ?usage:string -> unit
+
--- fsharp-3.1.1.26+dfsg2.orig/FSharp.PowerPack/AssemblyInfo.fs
+++ fsharp-3.1.1.26+dfsg2/FSharp.PowerPack/AssemblyInfo.fs
@@ -1,25 +1,25 @@
-namespace Microsoft.FSharp
-open System.Reflection
-[<assembly:AssemblyDescription("FSharp.PowerPack.dll")>]
-[<assembly:AssemblyCompany("F# PowerPack CodePlex Project")>]
-[<assembly:AssemblyTitle("FSharp.PowerPack.dll")>]
-[<assembly:AssemblyProduct("F# Power Pack")>]
-[<assembly: AutoOpen("Microsoft.FSharp.Text")>]
-[<assembly: AutoOpen("Microsoft.FSharp.Control")>]
-[<assembly: AutoOpen("Microsoft.FSharp.Collections")>]
-[<assembly: AutoOpen("Microsoft.FSharp.Core")>]
-[<assembly: AutoOpen("Microsoft.FSharp.Math")>]
-[<assembly: AutoOpen("Microsoft.FSharp")>]
-[<assembly: System.Runtime.InteropServices.ComVisible(false)>]
-[<assembly: System.CLSCompliant(true)>]
-//[<assembly: System.Security.SecurityTransparent>]
-#if FX_NO_SECURITY_PERMISSIONS
-#else
-#if FX_SIMPLE_SECURITY_PERMISSIONS
-[<assembly: System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.RequestMinimum)>]
-#else
-#endif
-#endif
-do()
-
-
+namespace Microsoft.FSharp
+open System.Reflection
+[<assembly:AssemblyDescription("FSharp.PowerPack.dll")>]
+[<assembly:AssemblyCompany("F# PowerPack CodePlex Project")>]
+[<assembly:AssemblyTitle("FSharp.PowerPack.dll")>]
+[<assembly:AssemblyProduct("F# Power Pack")>]
+[<assembly: AutoOpen("Microsoft.FSharp.Text")>]
+[<assembly: AutoOpen("Microsoft.FSharp.Control")>]
+[<assembly: AutoOpen("Microsoft.FSharp.Collections")>]
+[<assembly: AutoOpen("Microsoft.FSharp.Core")>]
+[<assembly: AutoOpen("Microsoft.FSharp.Math")>]
+[<assembly: AutoOpen("Microsoft.FSharp")>]
+[<assembly: System.Runtime.InteropServices.ComVisible(false)>]
+[<assembly: System.CLSCompliant(true)>]
+//[<assembly: System.Security.SecurityTransparent>]
+#if FX_NO_SECURITY_PERMISSIONS
+#else
+#if FX_SIMPLE_SECURITY_PERMISSIONS
+[<assembly: System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.RequestMinimum)>]
+#else
+#endif
+#endif
+do()
+
+
--- fsharp-3.1.1.26+dfsg2.orig/FSharp.PowerPack/AsyncOperations.fs
+++ fsharp-3.1.1.26+dfsg2/FSharp.PowerPack/AsyncOperations.fs
@@ -1,167 +1,167 @@
-// (c) Microsoft Corporation 2005-2009. 
-namespace Microsoft.FSharp.Control
-
-    open System
-    open System.Threading
-    open Microsoft.FSharp.Control
-
-    /// Represents the reified result of an asynchronous computation
-    [<NoEquality; NoComparison>]
-    type AsyncResult<'T>  =
-        |   AsyncOk of 'T
-        |   AsyncException of exn
-        |   AsyncCanceled of OperationCanceledException
-
-        static member Commit(res:AsyncResult<'T>) = 
-            Async.FromContinuations (fun (cont,econt,ccont) -> 
-                   match res with 
-                   | AsyncOk v -> cont v 
-                   | AsyncException exn -> econt exn 
-                   | AsyncCanceled exn -> ccont exn)
-
-    /// When using .NET 4.0 you can replace this type by Task<'T>
-    [<Sealed>]
-    type AsyncResultCell<'T>() =
-        let mutable result = None
-        // The continuation for the result, if any
-        let mutable savedConts = []
-        
-        let syncRoot = new obj()
-                
-
-        // Record the result in the AsyncResultCell.
-        // Ignore subsequent sets of the result. This can happen, e.g. for a race between 
-        // a cancellation and a success.
-        member x.RegisterResult (res:AsyncResult<'T>,?reuseThread) =
-            let grabbedConts = 
-                lock syncRoot (fun () ->
-                    if result.IsSome then  
-                        []
-                    else
-                        result <- Some res;
-                        // Invoke continuations in FIFO order 
-                        // Continuations that Async.FromContinuations provide do QUWI/SynchContext.Post, 
-                        // so the order is not overly relevant but still.                        
-                        List.rev savedConts)
-            // Run continuations outside the lock
-            let reuseThread = defaultArg reuseThread false
-            match grabbedConts with
-            |   [] -> ()
-            |   [cont] when reuseThread -> cont res
-            |   otherwise ->
-#if FX_NO_SYNC_CONTEXT
-                    let postOrQueue cont = ThreadPool.QueueUserWorkItem(fun _ -> cont res) |> ignore
-#else
-                    let synchContext = System.Threading.SynchronizationContext.Current
-                    let postOrQueue =
-                        match synchContext with
-                        |   null -> fun cont -> ThreadPool.QueueUserWorkItem(fun _ -> cont res) |> ignore
-                        |   sc -> fun cont -> sc.Post((fun _ -> cont res), state=null)
-#endif                        
-                    grabbedConts |> List.iter postOrQueue
-
-        /// Get the reified result 
-        member private x.AsyncPrimitiveResult =
-            Async.FromContinuations(fun (cont,_,_) -> 
-                let grabbedResult = 
-                    lock syncRoot (fun () ->
-                        match result with
-                        | Some res -> 
-                            result
-                        | None ->
-                            // Otherwise save the continuation and call it in RegisterResult
-                            savedConts <- cont::savedConts
-                            None)
-                // Run the action outside the lock
-                match grabbedResult with 
-                | None -> ()
-                | Some res -> cont res) 
-                           
-
-        /// Get the result and commit it
-        member x.AsyncResult =
-            async { let! res = x.AsyncPrimitiveResult
-                    return! AsyncResult.Commit(res) }
-
-
-    [<AutoOpen>]
-    module FileExtensions =
-
-        let UnblockViaNewThread f =
-            async { do! Async.SwitchToNewThread ()
-                    let res = f()
-                    do! Async.SwitchToThreadPool ()
-                    return res }
-
-
-        type System.IO.File with
-            static member AsyncOpenText(path)   = UnblockViaNewThread (fun () -> System.IO.File.OpenText(path))
-            static member AsyncAppendText(path) = UnblockViaNewThread (fun () -> System.IO.File.AppendText(path))
-            static member AsyncOpenRead(path)   = UnblockViaNewThread (fun () -> System.IO.File.OpenRead(path))
-            static member AsyncOpenWrite(path)  = UnblockViaNewThread (fun () -> System.IO.File.OpenWrite(path))
-#if FX_NO_FILE_OPTIONS
-            static member AsyncOpen(path,mode,?access,?share,?bufferSize) =
-#else
-            static member AsyncOpen(path,mode,?access,?share,?bufferSize,?options) =
-#endif
-                let access = match access with Some v -> v | None -> System.IO.FileAccess.ReadWrite
-                let share = match share with Some v -> v | None -> System.IO.FileShare.None
-#if FX_NO_FILE_OPTIONS
-#else
-                let options = match options with Some v -> v | None -> System.IO.FileOptions.None
-#endif
-                let bufferSize = match bufferSize with Some v -> v | None -> 0x1000
-                UnblockViaNewThread (fun () -> 
-#if FX_NO_FILE_OPTIONS
-                    new System.IO.FileStream(path,mode,access,share,bufferSize))
-#else
-                    new System.IO.FileStream(path,mode,access,share,bufferSize, options))
-#endif
-
-            static member OpenTextAsync(path)   = System.IO.File.AsyncOpenText(path)
-            static member AppendTextAsync(path) = System.IO.File.AsyncAppendText(path)
-            static member OpenReadAsync(path)   = System.IO.File.AsyncOpenRead(path)
-            static member OpenWriteAsync(path)  = System.IO.File.AsyncOpenWrite(path)
-#if FX_NO_FILE_OPTIONS
-            static member OpenAsync(path,mode,?access,?share,?bufferSize) = 
-                System.IO.File.AsyncOpen(path, mode, ?access=access, ?share=share,?bufferSize=bufferSize)
-#else
-            static member OpenAsync(path,mode,?access,?share,?bufferSize,?options) = 
-                System.IO.File.AsyncOpen(path, mode, ?access=access, ?share=share,?bufferSize=bufferSize,?options=options)
-#endif
-
-    [<AutoOpen>]
-    module StreamReaderExtensions =
-        type System.IO.StreamReader with
-
-            member s.AsyncReadToEnd () = FileExtensions.UnblockViaNewThread (fun () -> s.ReadToEnd())
-            member s.ReadToEndAsync () = s.AsyncReadToEnd ()
-
-#if FX_NO_WEB_REQUESTS
-#else
-    [<AutoOpen>]
-    module WebRequestExtensions =
-        open System
-        open System.Net
-        open Microsoft.FSharp.Control.WebExtensions
-
-        let callFSharpCoreAsyncGetResponse (req: System.Net.WebRequest) = req.AsyncGetResponse()
-        
-        type System.Net.WebRequest with
-            member req.AsyncGetResponse() = callFSharpCoreAsyncGetResponse req // this calls the FSharp.Core method
-            member req.GetResponseAsync() = callFSharpCoreAsyncGetResponse req // this calls the FSharp.Core method
-#endif
-     
-#if FX_NO_WEB_CLIENT
-#else
-    [<AutoOpen>]
-    module WebClientExtensions =
-        open System.Net
-        open Microsoft.FSharp.Control.WebExtensions
-        
-        let callFSharpCoreAsyncDownloadString (req: System.Net.WebClient) address = req.AsyncDownloadString address
-
-        type WebClient with
-            member this.AsyncDownloadString address = callFSharpCoreAsyncDownloadString this address
-#endif
-
+// (c) Microsoft Corporation 2005-2009. 
+namespace Microsoft.FSharp.Control
+
+    open System
+    open System.Threading
+    open Microsoft.FSharp.Control
+
+    /// Represents the reified result of an asynchronous computation
+    [<NoEquality; NoComparison>]
+    type AsyncResult<'T>  =
+        |   AsyncOk of 'T
+        |   AsyncException of exn
+        |   AsyncCanceled of OperationCanceledException
+
+        static member Commit(res:AsyncResult<'T>) = 
+            Async.FromContinuations (fun (cont,econt,ccont) -> 
+                   match res with 
+                   | AsyncOk v -> cont v 
+                   | AsyncException exn -> econt exn 
+                   | AsyncCanceled exn -> ccont exn)
+
+    /// When using .NET 4.0 you can replace this type by Task<'T>
+    [<Sealed>]
+    type AsyncResultCell<'T>() =
+        let mutable result = None
+        // The continuation for the result, if any
+        let mutable savedConts = []
+        
+        let syncRoot = new obj()
+                
+
+        // Record the result in the AsyncResultCell.
+        // Ignore subsequent sets of the result. This can happen, e.g. for a race between 
+        // a cancellation and a success.
+        member x.RegisterResult (res:AsyncResult<'T>,?reuseThread) =
+            let grabbedConts = 
+                lock syncRoot (fun () ->
+                    if result.IsSome then  
+                        []
+                    else
+                        result <- Some res;
+                        // Invoke continuations in FIFO order 
+                        // Continuations that Async.FromContinuations provide do QUWI/SynchContext.Post, 
+                        // so the order is not overly relevant but still.                        
+                        List.rev savedConts)
+            // Run continuations outside the lock
+            let reuseThread = defaultArg reuseThread false
+            match grabbedConts with
+            |   [] -> ()
+            |   [cont] when reuseThread -> cont res
+            |   otherwise ->
+#if FX_NO_SYNC_CONTEXT
+                    let postOrQueue cont = ThreadPool.QueueUserWorkItem(fun _ -> cont res) |> ignore
+#else
+                    let synchContext = System.Threading.SynchronizationContext.Current
+                    let postOrQueue =
+                        match synchContext with
+                        |   null -> fun cont -> ThreadPool.QueueUserWorkItem(fun _ -> cont res) |> ignore
+                        |   sc -> fun cont -> sc.Post((fun _ -> cont res), state=null)
+#endif                        
+                    grabbedConts |> List.iter postOrQueue
+
+        /// Get the reified result 
+        member private x.AsyncPrimitiveResult =
+            Async.FromContinuations(fun (cont,_,_) -> 
+                let grabbedResult = 
+                    lock syncRoot (fun () ->
+                        match result with
+                        | Some res -> 
+                            result
+                        | None ->
+                            // Otherwise save the continuation and call it in RegisterResult
+                            savedConts <- cont::savedConts
+                            None)
+                // Run the action outside the lock
+                match grabbedResult with 
+                | None -> ()
+                | Some res -> cont res) 
+                           
+
+        /// Get the result and commit it
+        member x.AsyncResult =
+            async { let! res = x.AsyncPrimitiveResult
+                    return! AsyncResult.Commit(res) }
+
+
+    [<AutoOpen>]
+    module FileExtensions =
+
+        let UnblockViaNewThread f =
+            async { do! Async.SwitchToNewThread ()
+                    let res = f()
+                    do! Async.SwitchToThreadPool ()
+                    return res }
+
+
+        type System.IO.File with
+            static member AsyncOpenText(path)   = UnblockViaNewThread (fun () -> System.IO.File.OpenText(path))
+            static member AsyncAppendText(path) = UnblockViaNewThread (fun () -> System.IO.File.AppendText(path))
+            static member AsyncOpenRead(path)   = UnblockViaNewThread (fun () -> System.IO.File.OpenRead(path))
+            static member AsyncOpenWrite(path)  = UnblockViaNewThread (fun () -> System.IO.File.OpenWrite(path))
+#if FX_NO_FILE_OPTIONS
+            static member AsyncOpen(path,mode,?access,?share,?bufferSize) =
+#else
+            static member AsyncOpen(path,mode,?access,?share,?bufferSize,?options) =
+#endif
+                let access = match access with Some v -> v | None -> System.IO.FileAccess.ReadWrite
+                let share = match share with Some v -> v | None -> System.IO.FileShare.None
+#if FX_NO_FILE_OPTIONS
+#else
+                let options = match options with Some v -> v | None -> System.IO.FileOptions.None
+#endif
+                let bufferSize = match bufferSize with Some v -> v | None -> 0x1000
+                UnblockViaNewThread (fun () -> 
+#if FX_NO_FILE_OPTIONS
+                    new System.IO.FileStream(path,mode,access,share,bufferSize))
+#else
+                    new System.IO.FileStream(path,mode,access,share,bufferSize, options))
+#endif
+
+            static member OpenTextAsync(path)   = System.IO.File.AsyncOpenText(path)
+            static member AppendTextAsync(path) = System.IO.File.AsyncAppendText(path)
+            static member OpenReadAsync(path)   = System.IO.File.AsyncOpenRead(path)
+            static member OpenWriteAsync(path)  = System.IO.File.AsyncOpenWrite(path)
+#if FX_NO_FILE_OPTIONS
+            static member OpenAsync(path,mode,?access,?share,?bufferSize) = 
+                System.IO.File.AsyncOpen(path, mode, ?access=access, ?share=share,?bufferSize=bufferSize)
+#else
+            static member OpenAsync(path,mode,?access,?share,?bufferSize,?options) = 
+                System.IO.File.AsyncOpen(path, mode, ?access=access, ?share=share,?bufferSize=bufferSize,?options=options)
+#endif
+
+    [<AutoOpen>]
+    module StreamReaderExtensions =
+        type System.IO.StreamReader with
+
+            member s.AsyncReadToEnd () = FileExtensions.UnblockViaNewThread (fun () -> s.ReadToEnd())
+            member s.ReadToEndAsync () = s.AsyncReadToEnd ()
+
+#if FX_NO_WEB_REQUESTS
+#else
+    [<AutoOpen>]
+    module WebRequestExtensions =
+        open System
+        open System.Net
+        open Microsoft.FSharp.Control.WebExtensions
+
+        let callFSharpCoreAsyncGetResponse (req: System.Net.WebRequest) = req.AsyncGetResponse()
+        
+        type System.Net.WebRequest with
+            member req.AsyncGetResponse() = callFSharpCoreAsyncGetResponse req // this calls the FSharp.Core method
+            member req.GetResponseAsync() = callFSharpCoreAsyncGetResponse req // this calls the FSharp.Core method
+#endif
+     
+#if FX_NO_WEB_CLIENT
+#else
+    [<AutoOpen>]
+    module WebClientExtensions =
+        open System.Net
+        open Microsoft.FSharp.Control.WebExtensions
+        
+        let callFSharpCoreAsyncDownloadString (req: System.Net.WebClient) address = req.AsyncDownloadString address
+
+        type WebClient with
+            member this.AsyncDownloadString address = callFSharpCoreAsyncDownloadString this address
+#endif
+
--- fsharp-3.1.1.26+dfsg2.orig/FSharp.PowerPack/AsyncOperations.fsi
+++ fsharp-3.1.1.26+dfsg2/FSharp.PowerPack/AsyncOperations.fsi
@@ -1,81 +1,81 @@
-// (c) Microsoft Corporation 2005-2009.
-namespace Microsoft.FSharp.Control
-
-    open System
-    open Microsoft.FSharp.Control
-    
-    /// Represents the reified result of an asynchronous computation
-    [<NoEquality; NoComparison>]
-    type AsyncResult<'T>  =
-        | AsyncOk of 'T
-        | AsyncException of exn
-        | AsyncCanceled of OperationCanceledException
-
-        /// Create an async whose result depends on the value of an AsyncResult.
-        static member Commit : AsyncResult<'T> -> Async<'T>
-
-    [<Sealed>]
-    /// A helper type to store a single result from an asynchronous computation and asynchronously
-    /// access its result.
-    type AsyncResultCell<'T> =
-        /// Record the result in the AsyncResultCell. Subsequent sets of the result are ignored. 
-        ///
-        /// This may result in the scheduled resumption of a waiting asynchronous operation  
-        member RegisterResult:AsyncResult<'T> * ?reuseThread:bool -> unit
-
-        /// Wait for the result and commit it
-        member AsyncResult : Async<'T>
-        /// Create a new result cell
-        new : unit -> AsyncResultCell<'T>
-        
-    [<AutoOpen>]
-    module StreamReaderExtensions =
-        open System.IO
-
-        type System.IO.StreamReader with 
-            /// Return an asynchronous computation that will read to the end of a stream via a fresh I/O thread.
-            member AsyncReadToEnd: unit -> Async<string>
-
-    [<AutoOpen>]
-    module FileExtensions =
-        open System.IO
-        type System.IO.File with 
-            /// Create an async that opens an existing file for reading, via a fresh I/O thread.
-            static member AsyncOpenText: path:string -> Async<StreamReader>
-
-            /// Create an async that opens a <c>System.IO.FileStream</c> on the specified path for read/write access, via a fresh I/O thread.
-            static member AsyncOpenRead: path:string -> Async<FileStream>
-
-            /// Create an async that opens an existing file writing, via a fresh I/O thread.
-            static member AsyncOpenWrite: path:string -> Async<FileStream>
-
-            /// Create an async that returns a <c>System.IO.StreamWriter</c> that appends UTF-8 text to an existing file, via a fresh I/O thread.
-            static member AsyncAppendText: path:string -> Async<StreamWriter>
-
-            /// Create an async that opens a <c>System.IO.FileStream</c> on the specified path, via a fresh I/O thread.
-            /// Pass <c>options=FileOptions.Asynchronous</c> to enable further asynchronous read/write operations
-            /// on the FileStream.
-#if FX_NO_FILE_OPTIONS
-            static member AsyncOpen: path:string * mode:FileMode * ?access: FileAccess * ?share: FileShare * ?bufferSize: int -> Async<FileStream>
-#else
-            static member AsyncOpen: path:string * mode:FileMode * ?access: FileAccess * ?share: FileShare * ?bufferSize: int * ?options: FileOptions -> Async<FileStream>
-#endif
-
-#if FX_NO_WEB_REQUESTS
-#else
-    [<AutoOpen>]
-    module WebRequestExtensions =
-        type System.Net.WebRequest with 
-            /// Return an asynchronous computation that, when run, will wait for a response to the given WebRequest.
-            [<System.Obsolete("The extension method now resides in the 'WebExtensions' module in the F# core library. Please add 'open Microsoft.FSharp.Control.WebExtensions' to access this method")>]
-            member AsyncGetResponse : unit -> Async<System.Net.WebResponse>
-#endif
-    
-#if FX_NO_WEB_CLIENT
-#else
-    [<AutoOpen>]
-    module WebClientExtensions =
-        type System.Net.WebClient with
-            [<System.Obsolete("The extension method now resides in the 'WebExtensions' module in the F# core library. Please add 'open Microsoft.FSharp.Control.WebExtensions' to access this method")>]
-            member AsyncDownloadString : address:System.Uri -> Async<string>
-#endif
+// (c) Microsoft Corporation 2005-2009.
+namespace Microsoft.FSharp.Control
+
+    open System
+    open Microsoft.FSharp.Control
+    
+    /// Represents the reified result of an asynchronous computation
+    [<NoEquality; NoComparison>]
+    type AsyncResult<'T>  =
+        | AsyncOk of 'T
+        | AsyncException of exn
+        | AsyncCanceled of OperationCanceledException
+
+        /// Create an async whose result depends on the value of an AsyncResult.
+        static member Commit : AsyncResult<'T> -> Async<'T>
+
+    [<Sealed>]
+    /// A helper type to store a single result from an asynchronous computation and asynchronously
+    /// access its result.
+    type AsyncResultCell<'T> =
+        /// Record the result in the AsyncResultCell. Subsequent sets of the result are ignored. 
+        ///
+        /// This may result in the scheduled resumption of a waiting asynchronous operation  
+        member RegisterResult:AsyncResult<'T> * ?reuseThread:bool -> unit
+
+        /// Wait for the result and commit it
+        member AsyncResult : Async<'T>
+        /// Create a new result cell
+        new : unit -> AsyncResultCell<'T>
+        
+    [<AutoOpen>]
+    module StreamReaderExtensions =
+        open System.IO
+
+        type System.IO.StreamReader with 
+            /// Return an asynchronous computation that will read to the end of a stream via a fresh I/O thread.
+            member AsyncReadToEnd: unit -> Async<string>
+
+    [<AutoOpen>]
+    module FileExtensions =
+        open System.IO
+        type System.IO.File with 
+            /// Create an async that opens an existing file for reading, via a fresh I/O thread.
+            static member AsyncOpenText: path:string -> Async<StreamReader>
+
+            /// Create an async that opens a <c>System.IO.FileStream</c> on the specified path for read/write access, via a fresh I/O thread.
+            static member AsyncOpenRead: path:string -> Async<FileStream>
+
+            /// Create an async that opens an existing file writing, via a fresh I/O thread.
+            static member AsyncOpenWrite: path:string -> Async<FileStream>
+
+            /// Create an async that returns a <c>System.IO.StreamWriter</c> that appends UTF-8 text to an existing file, via a fresh I/O thread.
+            static member AsyncAppendText: path:string -> Async<StreamWriter>
+
+            /// Create an async that opens a <c>System.IO.FileStream</c> on the specified path, via a fresh I/O thread.
+            /// Pass <c>options=FileOptions.Asynchronous</c> to enable further asynchronous read/write operations
+            /// on the FileStream.
+#if FX_NO_FILE_OPTIONS
+            static member AsyncOpen: path:string * mode:FileMode * ?access: FileAccess * ?share: FileShare * ?bufferSize: int -> Async<FileStream>
+#else
+            static member AsyncOpen: path:string * mode:FileMode * ?access: FileAccess * ?share: FileShare * ?bufferSize: int * ?options: FileOptions -> Async<FileStream>
+#endif
+
+#if FX_NO_WEB_REQUESTS
+#else
+    [<AutoOpen>]
+    module WebRequestExtensions =
+        type System.Net.WebRequest with 
+            /// Return an asynchronous computation that, when run, will wait for a response to the given WebRequest.
+            [<System.Obsolete("The extension method now resides in the 'WebExtensions' module in the F# core library. Please add 'open Microsoft.FSharp.Control.WebExtensions' to access this method")>]
+            member AsyncGetResponse : unit -> Async<System.Net.WebResponse>
+#endif
+    
+#if FX_NO_WEB_CLIENT
+#else
+    [<AutoOpen>]
+    module WebClientExtensions =
+        type System.Net.WebClient with
+            [<System.Obsolete("The extension method now resides in the 'WebExtensions' module in the F# core library. Please add 'open Microsoft.FSharp.Control.WebExtensions' to access this method")>]
+            member AsyncDownloadString : address:System.Uri -> Async<string>
+#endif
--- fsharp-3.1.1.26+dfsg2.orig/FSharp.PowerPack/AsyncStreamReader.fs
+++ fsharp-3.1.1.26+dfsg2/FSharp.PowerPack/AsyncStreamReader.fs
@@ -1,429 +1,429 @@
-﻿namespace Microsoft.FSharp.Control
-
-open System
-open System.Diagnostics
-open System.IO
-open System.Text
-
-/// <summary>
-/// Implements a TextReader-like API that asynchronously reads characters from 
-/// a byte stream in a particular encoding.
-/// </summary>
-[<Sealed>]
-type AsyncStreamReader(stream:Stream, encoding:Encoding, detectEncodingFromByteOrderMarks:bool, bufferSize:int) =
-    static let defaultBufferSize = 1024;  // Byte buffer size
-    static let defaultFileStreamBufferSize = 4096;
-    static let minBufferSize = 128; 
-
-    // Creates a new StreamReader for the given stream.  The 
-    // character encoding is set by encoding and the buffer size,
-    // in number of 16-bit characters, is set by bufferSize. 
-    // 
-    // Note that detectEncodingFromByteOrderMarks is a very
-    // loose attempt at detecting the encoding by looking at the first 
-    // 3 bytes of the stream.  It will recognize UTF-8, little endian
-    // unicode, and big endian unicode text, but that's it.  If neither
-    // of those three match, it will use the Encoding you provided.
-    // 
-
-    do  if (stream=null || encoding=null) then 
-            raise <| new ArgumentNullException(if (stream=null) then "stream" else "encoding");
-
-        if not stream.CanRead then
-            invalidArg "stream" "stream not readable";
-#if FX_NO_FILESTREAM_ISASYNC
-#else
-        match stream with 
-        | :? System.IO.FileStream as fs when not fs.IsAsync -> 
-            invalidArg "stream" "FileStream not asynchronous. AsyncStreamReader should only be used on FileStream if the IsAsync property returns true. Consider passing 'true' for the async flag in the FileStream constructor"
-        | _ -> 
-            ()
-#endif
-        if (bufferSize <= 0) then
-            raise <| new ArgumentOutOfRangeException("bufferSize");
-
-    let mutable stream = stream
-    let mutable decoder = encoding.GetDecoder();
-    let mutable encoding = encoding
-    let bufferSize = max bufferSize  minBufferSize; 
-
-    // This is the maximum number of chars we can get from one call to
-    // readBuffer.  Used so readBuffer can tell when to copy data into 
-    // a user's char[] directly, instead of our internal char[].
-    let mutable _maxCharsPerBuffer = encoding.GetMaxCharCount(bufferSize) 
-    let mutable byteBuffer = Array.zeroCreate<byte> bufferSize;
-    let mutable charBuffer = Array.zeroCreate<char> _maxCharsPerBuffer;
-    let preamble = encoding.GetPreamble();   // Encoding's preamble, which identifies this encoding. 
-    let mutable charPos = 0
-    let mutable charLen = 0
-    // Record the number of valid bytes in the byteBuffer, for a few checks. 
-    let mutable byteLen = 0
-    // This is used only for preamble detection 
-    let mutable bytePos = 0
-
-    // We will support looking for byte order marks in the stream and trying
-    // to decide what the encoding might be from the byte order marks, IF they 
-    // exist.  But that's all we'll do.
-    let mutable _detectEncoding = detectEncodingFromByteOrderMarks;
-
-    // Whether we must still check for the encoding's given preamble at the 
-    // beginning of this file.
-    let mutable _checkPreamble = (preamble.Length > 0); 
-
-    let readerClosed() = invalidOp "reader closed"
-    // Trims n bytes from the front of the buffer.
-    let compressBuffer(n) =
-        Debug.Assert(byteLen >= n, "compressBuffer was called with a number of bytes greater than the current buffer length.  Are two threads using this StreamReader at the same time?");
-        Buffer.BlockCopy(byteBuffer, n, byteBuffer, 0, byteLen - n);
-        byteLen <- byteLen - n; 
-
-    // Trims the preamble bytes from the byteBuffer. This routine can be called multiple times
-    // and we will buffer the bytes read until the preamble is matched or we determine that
-    // there is no match. If there is no match, every byte read previously will be available 
-    // for further consumption. If there is a match, we will compress the buffer for the
-    // leading preamble bytes 
-    let isPreamble() = 
-        if not _checkPreamble then _checkPreamble else
-
-        Debug.Assert(bytePos <= preamble.Length, "_compressPreamble was called with the current bytePos greater than the preamble buffer length.  Are two threads using this StreamReader at the same time?");
-        let len = if (byteLen >= (preamble.Length)) then (preamble.Length - bytePos) else (byteLen  - bytePos); 
-
-        let mutable fin = false
-        let mutable i = 0
-        while i < len && not fin do
-            if (byteBuffer.[bytePos] <> preamble.[bytePos]) then
-                bytePos <- 0;
-                _checkPreamble <- false; 
-                fin <- true
-            if not fin then 
-                i <- i + 1
-                bytePos <- bytePos + 1
-
-        Debug.Assert(bytePos <= preamble.Length, "possible bug in _compressPreamble.  Are two threads using this StreamReader at the same time?");
-
-        if (_checkPreamble) then
-            if (bytePos = preamble.Length) then
-                // We have a match 
-                compressBuffer(preamble.Length);
-                bytePos <- 0;
-                _checkPreamble <- false;
-                _detectEncoding <- false; 
-
-        _checkPreamble;
-
-
-    let detectEncoding() =
-        if (byteLen >= 2) then 
-            _detectEncoding <- false;
-            let mutable changedEncoding = false;
-            if (byteBuffer.[0]=0xFEuy && byteBuffer.[1]=0xFFuy) then
-                // Big Endian Unicode
-
-                encoding <- new UnicodeEncoding(true, true); 
-                compressBuffer(2);
-                changedEncoding <- true; 
-#if FX_NO_UTF32ENCODING
-#else
-            elif (byteBuffer.[0]=0xFFuy && byteBuffer.[1]=0xFEuy) then
-                // Little Endian Unicode, or possibly little endian UTF32
-                if (byteLen >= 4 && byteBuffer.[2] = 0uy && byteBuffer.[3] = 0uy) then
-                    encoding <- new UTF32Encoding(false, true);
-                    compressBuffer(4); 
-                else 
-                    encoding <- new UnicodeEncoding(false, true); 
-                    compressBuffer(2);
-                changedEncoding <- true;
-#endif
-            elif (byteLen >= 3 && byteBuffer.[0]=0xEFuy && byteBuffer.[1]=0xBBuy && byteBuffer.[2]=0xBFuy) then
-                // UTF-8 
-                encoding <- Encoding.UTF8; 
-                compressBuffer(3);
-                changedEncoding <- true; 
-#if FX_NO_UTF32ENCODING
-#else
-            elif (byteLen >= 4 && byteBuffer.[0] = 0uy && byteBuffer.[1] = 0uy && byteBuffer.[2] = 0xFEuy && byteBuffer.[3] = 0xFFuy) then
-                // Big Endian UTF32 
-                encoding <- new UTF32Encoding(true, true);
-                changedEncoding <- true; 
-#endif
-            elif (byteLen = 2) then
-                _detectEncoding <- true; 
-            // Note: in the future, if we change this algorithm significantly,
-            // we can support checking for the preamble of the given encoding.
-
-            if (changedEncoding) then 
-                decoder <- encoding.GetDecoder();
-                _maxCharsPerBuffer <- encoding.GetMaxCharCount(byteBuffer.Length); 
-                charBuffer <- Array.zeroCreate<char> _maxCharsPerBuffer; 
-
-    let readBuffer() = async {
-        charLen <- 0;
-        charPos <- 0; 
-
-        if not _checkPreamble then
-            byteLen <- 0; 
-
-        let fin = ref false
-        while (charLen = 0 && not !fin) do
-            if (_checkPreamble) then 
-                Debug.Assert(bytePos <= preamble.Length, "possible bug in _compressPreamble.  Are two threads using this StreamReader at the same time?");
-                let! len = stream.AsyncRead(byteBuffer, bytePos, byteBuffer.Length - bytePos);
-                Debug.Assert(len >= 0, "Stream.Read returned a negative number!  This is a bug in your stream class.");
-
-                if (len = 0) then
-                    // EOF but we might have buffered bytes from previous 
-                    // attempts to detecting preamble that needs to decoded now 
-                    if (byteLen > 0) then
-                        charLen <-  charLen + decoder.GetChars(byteBuffer, 0, byteLen, charBuffer, charLen); 
-
-                    fin := true
-                
-                byteLen <- byteLen + len;
-            else 
-                Debug.Assert((bytePos = 0), "bytePos can be non zero only when we are trying to _checkPreamble.  Are two threads using this StreamReader at the same time?");
-                let! len = stream.AsyncRead(byteBuffer, 0, byteBuffer.Length); 
-                byteLen <- len
-                Debug.Assert(byteLen >= 0, "Stream.Read returned a negative number!  This is a bug in your stream class.");
-
-                if (byteLen = 0)  then // We're at EOF
-                    fin := true
-
-            // Check for preamble before detect encoding. This is not to override the
-            // user suppplied Encoding for the one we implicitly detect. The user could 
-            // customize the encoding which we will loose, such as ThrowOnError on UTF8
-            if not !fin then 
-                if not (isPreamble()) then
-                    // If we're supposed to detect the encoding and haven't done so yet, 
-                    // do it.  Note this may need to be called more than once.
-                    if (_detectEncoding && byteLen >= 2) then
-                        detectEncoding();
-
-                    charLen <- charLen + decoder.GetChars(byteBuffer, 0, byteLen, charBuffer, charLen);
-
-            if (charLen <> 0) then 
-                fin := true
-
-        return charLen
-
-    } 
-
-
-    let cleanup() = 
-            // Dispose of our resources if this StreamReader is closable.
-            // Note that Console.In should not be closable. 
-            try 
-                // Note that Stream.Close() can potentially throw here. So we need to
-                // ensure cleaning up internal resources, inside the finally block.
-                if (stream <> null) then
-                    stream.Close();
-            
-            finally 
-                if (stream <> null) then
-                    stream <- null; 
-                    encoding <- null;
-                    decoder <- null;
-                    byteBuffer <- null;
-                    charBuffer <- null; 
-                    charPos <- 0;
-                    charLen <- 0; 
-                    //REMOVED: base.Dispose(disposing); 
-
-    // StreamReader by default will ignore illegal UTF8 characters. We don't want to 
-    // throw here because we want to be able to read ill-formed data without choking.
-    // The high level goal is to be tolerant of encoding errors when we read and very strict 
-    // when we write. Hence, default StreamWriter encoding will throw on error.
-
-    new (stream) = new AsyncStreamReader(stream, true) 
-
-    new (stream, detectEncodingFromByteOrderMarks:bool) = new AsyncStreamReader(stream, Encoding.UTF8, detectEncodingFromByteOrderMarks, defaultBufferSize)
-
-    new (stream, encoding:Encoding) = new AsyncStreamReader(stream, encoding, true, defaultBufferSize) 
-
-    new (stream, encoding, detectEncodingFromByteOrderMarks) = new AsyncStreamReader(stream, encoding, detectEncodingFromByteOrderMarks, defaultBufferSize) 
-
-(*
-    new (path:string) = new AsyncStreamReader(path, true)
-
-    new (path: string, detectEncodingFromByteOrderMarks: bool) = new AsyncStreamReader (path, Encoding.UTF8, detectEncodingFromByteOrderMarks, defaultBufferSize) 
-
-    new (path:string, encoding:Encoding) = new AsyncStreamReader(path, encoding, true, defaultBufferSize) 
-
-    new (path: string, encoding:Encoding, detectEncodingFromByteOrderMarks: bool)  = new AsyncStreamReader(path, encoding, detectEncodingFromByteOrderMarks, defaultBufferSize) 
-
-    new (path: string, encoding: Encoding, detectEncodingFromByteOrderMarks: bool, bufferSize: int)  =
-        // Don't open a Stream before checking for invalid arguments, 
-        // or we'll create a FileStream on disk and we won't close it until 
-        // the finalizer runs, causing problems for applications.
-        if (path=null || encoding=null) then
-            raise <| new ArgumentNullException((path=null ? "path" : "encoding"));
-        if (path.Length=0) then
-            raise <| new ArgumentException((* Environment.GetResourceString *)("Argument_EmptyPath"));
-        if (bufferSize <= 0)  then
-            raise <| new ArgumentOutOfRangeException("bufferSize", (* Environment.GetResourceString *)("ArgumentOutOfRange_NeedPosNum"));
-
-        Stream stream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, defaultFileStreamBufferSize, FileOptions.SequentialScan); 
-        Init(stream, encoding, detectEncodingFromByteOrderMarks, bufferSize);
-
-*)
-
-    member x.Close() = cleanup()
-
-    interface System.IDisposable with 
-        member x.Dispose() = cleanup()
-
-    member x.CurrentEncoding  = encoding
-    member x.BaseStream = stream
-
-    // DiscardBufferedData tells StreamReader to throw away its internal 
-    // buffer contents.  This is useful if the user needs to seek on the
-    // underlying stream to a known location then wants the StreamReader 
-    // to start reading from this new point.  This method should be called
-    // very sparingly, if ever, since it can lead to very poor performance.
-    // However, it may be the only way of handling some scenarios where
-    // users need to re-read the contents of a StreamReader a second time. 
-    member x.DiscardBufferedData() =
-        byteLen <- 0; 
-        charLen <- 0; 
-        charPos <- 0;
-        decoder <- encoding.GetDecoder(); 
-
-    member x.EndOfStream = async {
-        if (stream = null) then
-            readerClosed(); 
-
-        if (charPos < charLen) then
-            return false
-        else
-            let! numRead = readBuffer(); 
-            return numRead = 0;
-    }
-
-    member x.Peek() = 
-        async {
-            let! emp = x.EndOfStream 
-            return (if emp then -1 else int charBuffer.[charPos])
-        }
-
-    member x.Read() = async {
-        if (stream = null) then
-            readerClosed();
-
-        if (charPos = charLen) then 
-            let! n = readBuffer() 
-            if n = 0 then 
-                return char -1; 
-            else
-                let result = charBuffer.[charPos];
-                charPos <- charPos + 1; 
-                return result;
-        else
-            let result = charBuffer.[charPos];
-            charPos <- charPos + 1; 
-            return result;
-    }
-    
-    // Returns only when count characters have been read or the end of the file was reached. 
-    member x.ReadExactly(buffer:char[], index, count) = async {
-        let i = ref 0
-        let n = ref 0 
-        let count = ref count
-        let first = ref true
-        while !first || (!i > 0 && !n < !count) do 
-            let! j = x.Read(buffer, index + !n, !count - !n)
-            i := j 
-            n := !n + j
-            first := false
-        return !n;
-    } 
-
-    member x.Read(buffer:char[], index, count) = async {
-        if (stream = null) then
-            readerClosed(); 
-        if (buffer=null) then
-            raise <| new ArgumentNullException("buffer");
-        if (index < 0 || count < 0) then
-            raise <| new ArgumentOutOfRangeException((if (index < 0) then "index" else "count"), (* Environment.GetResourceString *)("ArgumentOutOfRange_NeedNonNegNum"));
-        if (buffer.Length - index < count) then
-            raise <| new ArgumentException("index")
-
-        let charsRead = ref 0;
-        let charsReqd = ref count;
-        let fin = ref false
-        while (!charsReqd > 0) && not !fin do
-            let! charsAvail = if (charLen = charPos) then readBuffer() else async { return charLen - charPos }
-            if (charsAvail = 0) then 
-                // We're at EOF
-                fin := true 
-            else  
-                let charsConsumed = min charsAvail !charsReqd
-                Buffer.BlockCopy(charBuffer, charPos * 2, buffer, (index + !charsRead) * 2, charsConsumed*2); 
-                charPos <- charPos + charsConsumed; 
-                charsRead := !charsRead + charsConsumed; 
-                charsReqd := !charsReqd - charsConsumed;
-
-        return !charsRead;
-    } 
-
-    member x.ReadToEnd() = async {
-        if (stream = null) then
-            readerClosed();
-
-        // Call readBuffer, then pull data out of charBuffer. 
-        let sb = new StringBuilder(charLen - charPos);
-        let readNextChunk = 
-            async {
-                sb.Append(charBuffer, charPos, charLen - charPos) |> ignore;
-                charPos <- charLen;  // Note we consumed these characters
-                let! _ = readBuffer() 
-                return ()
-            }
-        do! readNextChunk
-        while charLen > 0 do 
-            do! readNextChunk
-        return sb.ToString();
-    } 
-
-
-    // Reads a line. A line is defined as a sequence of characters followed by 
-    // a carriage return ('\r'), a line feed ('\n'), or a carriage return
-    // immediately followed by a line feed. The resulting string does not 
-    // contain the terminating carriage return and/or line feed. The returned 
-    // value is null if the end of the input stream has been reached.
-    // 
-    member x.ReadLine() = async {
-
-        let! emp = x.EndOfStream
-        if emp then return null else
-        let sb = new StringBuilder()
-        let fin1 = ref false
-        while not !fin1 do 
-            let i = ref charPos;
-            let fin2 = ref false
-            while (!i < charLen) && not !fin2 do 
-                let ch = charBuffer.[!i];
-                // Note the following common line feed chars: 
-                // \n - UNIX   \r\n - DOS   \r - Mac
-                if (ch = '\r' || ch = '\n') then
-                    sb.Append(charBuffer, charPos, !i - charPos) |> ignore; 
-                    charPos <- !i + 1; 
-                    if ch = '\r' then 
-                        let! emp = x.EndOfStream
-                        if not emp && (charBuffer.[charPos] = '\n') then 
-                            charPos <- charPos + 1;
-                    // Found end of line, done
-                    fin2 := true
-                    fin1 := true
-                else
-                    i := !i + 1;
-
-            if not !fin1 then 
-                i := charLen - charPos;
-                sb.Append(charBuffer, charPos, !i) |> ignore; 
-
-                let! n = readBuffer() 
-                fin1 := (n <= 0)
-
-        return sb.ToString(); 
-
-    }
-
+﻿namespace Microsoft.FSharp.Control
+
+open System
+open System.Diagnostics
+open System.IO
+open System.Text
+
+/// <summary>
+/// Implements a TextReader-like API that asynchronously reads characters from 
+/// a byte stream in a particular encoding.
+/// </summary>
+[<Sealed>]
+type AsyncStreamReader(stream:Stream, encoding:Encoding, detectEncodingFromByteOrderMarks:bool, bufferSize:int) =
+    static let defaultBufferSize = 1024;  // Byte buffer size
+    static let defaultFileStreamBufferSize = 4096;
+    static let minBufferSize = 128; 
+
+    // Creates a new StreamReader for the given stream.  The 
+    // character encoding is set by encoding and the buffer size,
+    // in number of 16-bit characters, is set by bufferSize. 
+    // 
+    // Note that detectEncodingFromByteOrderMarks is a very
+    // loose attempt at detecting the encoding by looking at the first 
+    // 3 bytes of the stream.  It will recognize UTF-8, little endian
+    // unicode, and big endian unicode text, but that's it.  If neither
+    // of those three match, it will use the Encoding you provided.
+    // 
+
+    do  if (stream=null || encoding=null) then 
+            raise <| new ArgumentNullException(if (stream=null) then "stream" else "encoding");
+
+        if not stream.CanRead then
+            invalidArg "stream" "stream not readable";
+#if FX_NO_FILESTREAM_ISASYNC
+#else
+        match stream with 
+        | :? System.IO.FileStream as fs when not fs.IsAsync -> 
+            invalidArg "stream" "FileStream not asynchronous. AsyncStreamReader should only be used on FileStream if the IsAsync property returns true. Consider passing 'true' for the async flag in the FileStream constructor"
+        | _ -> 
+            ()
+#endif
+        if (bufferSize <= 0) then
+            raise <| new ArgumentOutOfRangeException("bufferSize");
+
+    let mutable stream = stream
+    let mutable decoder = encoding.GetDecoder();
+    let mutable encoding = encoding
+    let bufferSize = max bufferSize  minBufferSize; 
+
+    // This is the maximum number of chars we can get from one call to
+    // readBuffer.  Used so readBuffer can tell when to copy data into 
+    // a user's char[] directly, instead of our internal char[].
+    let mutable _maxCharsPerBuffer = encoding.GetMaxCharCount(bufferSize) 
+    let mutable byteBuffer = Array.zeroCreate<byte> bufferSize;
+    let mutable charBuffer = Array.zeroCreate<char> _maxCharsPerBuffer;
+    let preamble = encoding.GetPreamble();   // Encoding's preamble, which identifies this encoding. 
+    let mutable charPos = 0
+    let mutable charLen = 0
+    // Record the number of valid bytes in the byteBuffer, for a few checks. 
+    let mutable byteLen = 0
+    // This is used only for preamble detection 
+    let mutable bytePos = 0
+
+    // We will support looking for byte order marks in the stream and trying
+    // to decide what the encoding might be from the byte order marks, IF they 
+    // exist.  But that's all we'll do.
+    let mutable _detectEncoding = detectEncodingFromByteOrderMarks;
+
+    // Whether we must still check for the encoding's given preamble at the 
+    // beginning of this file.
+    let mutable _checkPreamble = (preamble.Length > 0); 
+
+    let readerClosed() = invalidOp "reader closed"
+    // Trims n bytes from the front of the buffer.
+    let compressBuffer(n) =
+        Debug.Assert(byteLen >= n, "compressBuffer was called with a number of bytes greater than the current buffer length.  Are two threads using this StreamReader at the same time?");
+        Buffer.BlockCopy(byteBuffer, n, byteBuffer, 0, byteLen - n);
+        byteLen <- byteLen - n; 
+
+    // Trims the preamble bytes from the byteBuffer. This routine can be called multiple times
+    // and we will buffer the bytes read until the preamble is matched or we determine that
+    // there is no match. If there is no match, every byte read previously will be available 
+    // for further consumption. If there is a match, we will compress the buffer for the
+    // leading preamble bytes 
+    let isPreamble() = 
+        if not _checkPreamble then _checkPreamble else
+
+        Debug.Assert(bytePos <= preamble.Length, "_compressPreamble was called with the current bytePos greater than the preamble buffer length.  Are two threads using this StreamReader at the same time?");
+        let len = if (byteLen >= (preamble.Length)) then (preamble.Length - bytePos) else (byteLen  - bytePos); 
+
+        let mutable fin = false
+        let mutable i = 0
+        while i < len && not fin do
+            if (byteBuffer.[bytePos] <> preamble.[bytePos]) then
+                bytePos <- 0;
+                _checkPreamble <- false; 
+                fin <- true
+            if not fin then 
+                i <- i + 1
+                bytePos <- bytePos + 1
+
+        Debug.Assert(bytePos <= preamble.Length, "possible bug in _compressPreamble.  Are two threads using this StreamReader at the same time?");
+
+        if (_checkPreamble) then
+            if (bytePos = preamble.Length) then
+                // We have a match 
+                compressBuffer(preamble.Length);
+                bytePos <- 0;
+                _checkPreamble <- false;
+                _detectEncoding <- false; 
+
+        _checkPreamble;
+
+
+    let detectEncoding() =
+        if (byteLen >= 2) then 
+            _detectEncoding <- false;
+            let mutable changedEncoding = false;
+            if (byteBuffer.[0]=0xFEuy && byteBuffer.[1]=0xFFuy) then
+                // Big Endian Unicode
+
+                encoding <- new UnicodeEncoding(true, true); 
+                compressBuffer(2);
+                changedEncoding <- true; 
+#if FX_NO_UTF32ENCODING
+#else
+            elif (byteBuffer.[0]=0xFFuy && byteBuffer.[1]=0xFEuy) then
+                // Little Endian Unicode, or possibly little endian UTF32
+                if (byteLen >= 4 && byteBuffer.[2] = 0uy && byteBuffer.[3] = 0uy) then
+                    encoding <- new UTF32Encoding(false, true);
+                    compressBuffer(4); 
+                else 
+                    encoding <- new UnicodeEncoding(false, true); 
+                    compressBuffer(2);
+                changedEncoding <- true;
+#endif
+            elif (byteLen >= 3 && byteBuffer.[0]=0xEFuy && byteBuffer.[1]=0xBBuy && byteBuffer.[2]=0xBFuy) then
+                // UTF-8 
+                encoding <- Encoding.UTF8; 
+                compressBuffer(3);
+                changedEncoding <- true; 
+#if FX_NO_UTF32ENCODING
+#else
+            elif (byteLen >= 4 && byteBuffer.[0] = 0uy && byteBuffer.[1] = 0uy && byteBuffer.[2] = 0xFEuy && byteBuffer.[3] = 0xFFuy) then
+                // Big Endian UTF32 
+                encoding <- new UTF32Encoding(true, true);
+                changedEncoding <- true; 
+#endif
+            elif (byteLen = 2) then
+                _detectEncoding <- true; 
+            // Note: in the future, if we change this algorithm significantly,
+            // we can support checking for the preamble of the given encoding.
+
+            if (changedEncoding) then 
+                decoder <- encoding.GetDecoder();
+                _maxCharsPerBuffer <- encoding.GetMaxCharCount(byteBuffer.Length); 
+                charBuffer <- Array.zeroCreate<char> _maxCharsPerBuffer; 
+
+    let readBuffer() = async {
+        charLen <- 0;
+        charPos <- 0; 
+
+        if not _checkPreamble then
+            byteLen <- 0; 
+
+        let fin = ref false
+        while (charLen = 0 && not !fin) do
+            if (_checkPreamble) then 
+                Debug.Assert(bytePos <= preamble.Length, "possible bug in _compressPreamble.  Are two threads using this StreamReader at the same time?");
+                let! len = stream.AsyncRead(byteBuffer, bytePos, byteBuffer.Length - bytePos);
+                Debug.Assert(len >= 0, "Stream.Read returned a negative number!  This is a bug in your stream class.");
+
+                if (len = 0) then
+                    // EOF but we might have buffered bytes from previous 
+                    // attempts to detecting preamble that needs to decoded now 
+                    if (byteLen > 0) then
+                        charLen <-  charLen + decoder.GetChars(byteBuffer, 0, byteLen, charBuffer, charLen); 
+
+                    fin := true
+                
+                byteLen <- byteLen + len;
+            else 
+                Debug.Assert((bytePos = 0), "bytePos can be non zero only when we are trying to _checkPreamble.  Are two threads using this StreamReader at the same time?");
+                let! len = stream.AsyncRead(byteBuffer, 0, byteBuffer.Length); 
+                byteLen <- len
+                Debug.Assert(byteLen >= 0, "Stream.Read returned a negative number!  This is a bug in your stream class.");
+
+                if (byteLen = 0)  then // We're at EOF
+                    fin := true
+
+            // Check for preamble before detect encoding. This is not to override the
+            // user suppplied Encoding for the one we implicitly detect. The user could 
+            // customize the encoding which we will loose, such as ThrowOnError on UTF8
+            if not !fin then 
+                if not (isPreamble()) then
+                    // If we're supposed to detect the encoding and haven't done so yet, 
+                    // do it.  Note this may need to be called more than once.
+                    if (_detectEncoding && byteLen >= 2) then
+                        detectEncoding();
+
+                    charLen <- charLen + decoder.GetChars(byteBuffer, 0, byteLen, charBuffer, charLen);
+
+            if (charLen <> 0) then 
+                fin := true
+
+        return charLen
+
+    } 
+
+
+    let cleanup() = 
+            // Dispose of our resources if this StreamReader is closable.
+            // Note that Console.In should not be closable. 
+            try 
+                // Note that Stream.Close() can potentially throw here. So we need to
+                // ensure cleaning up internal resources, inside the finally block.
+                if (stream <> null) then
+                    stream.Close();
+            
+            finally 
+                if (stream <> null) then
+                    stream <- null; 
+                    encoding <- null;
+                    decoder <- null;
+                    byteBuffer <- null;
+                    charBuffer <- null; 
+                    charPos <- 0;
+                    charLen <- 0; 
+                    //REMOVED: base.Dispose(disposing); 
+
+    // StreamReader by default will ignore illegal UTF8 characters. We don't want to 
+    // throw here because we want to be able to read ill-formed data without choking.
+    // The high level goal is to be tolerant of encoding errors when we read and very strict 
+    // when we write. Hence, default StreamWriter encoding will throw on error.
+
+    new (stream) = new AsyncStreamReader(stream, true) 
+
+    new (stream, detectEncodingFromByteOrderMarks:bool) = new AsyncStreamReader(stream, Encoding.UTF8, detectEncodingFromByteOrderMarks, defaultBufferSize)
+
+    new (stream, encoding:Encoding) = new AsyncStreamReader(stream, encoding, true, defaultBufferSize) 
+
+    new (stream, encoding, detectEncodingFromByteOrderMarks) = new AsyncStreamReader(stream, encoding, detectEncodingFromByteOrderMarks, defaultBufferSize) 
+
+(*
+    new (path:string) = new AsyncStreamReader(path, true)
+
+    new (path: string, detectEncodingFromByteOrderMarks: bool) = new AsyncStreamReader (path, Encoding.UTF8, detectEncodingFromByteOrderMarks, defaultBufferSize) 
+
+    new (path:string, encoding:Encoding) = new AsyncStreamReader(path, encoding, true, defaultBufferSize) 
+
+    new (path: string, encoding:Encoding, detectEncodingFromByteOrderMarks: bool)  = new AsyncStreamReader(path, encoding, detectEncodingFromByteOrderMarks, defaultBufferSize) 
+
+    new (path: string, encoding: Encoding, detectEncodingFromByteOrderMarks: bool, bufferSize: int)  =
+        // Don't open a Stream before checking for invalid arguments, 
+        // or we'll create a FileStream on disk and we won't close it until 
+        // the finalizer runs, causing problems for applications.
+        if (path=null || encoding=null) then
+            raise <| new ArgumentNullException((path=null ? "path" : "encoding"));
+        if (path.Length=0) then
+            raise <| new ArgumentException((* Environment.GetResourceString *)("Argument_EmptyPath"));
+        if (bufferSize <= 0)  then
+            raise <| new ArgumentOutOfRangeException("bufferSize", (* Environment.GetResourceString *)("ArgumentOutOfRange_NeedPosNum"));
+
+        Stream stream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, defaultFileStreamBufferSize, FileOptions.SequentialScan); 
+        Init(stream, encoding, detectEncodingFromByteOrderMarks, bufferSize);
+
+*)
+
+    member x.Close() = cleanup()
+
+    interface System.IDisposable with 
+        member x.Dispose() = cleanup()
+
+    member x.CurrentEncoding  = encoding
+    member x.BaseStream = stream
+
+    // DiscardBufferedData tells StreamReader to throw away its internal 
+    // buffer contents.  This is useful if the user needs to seek on the
+    // underlying stream to a known location then wants the StreamReader 
+    // to start reading from this new point.  This method should be called
+    // very sparingly, if ever, since it can lead to very poor performance.
+    // However, it may be the only way of handling some scenarios where
+    // users need to re-read the contents of a StreamReader a second time. 
+    member x.DiscardBufferedData() =
+        byteLen <- 0; 
+        charLen <- 0; 
+        charPos <- 0;
+        decoder <- encoding.GetDecoder(); 
+
+    member x.EndOfStream = async {
+        if (stream = null) then
+            readerClosed(); 
+
+        if (charPos < charLen) then
+            return false
+        else
+            let! numRead = readBuffer(); 
+            return numRead = 0;
+    }
+
+    member x.Peek() = 
+        async {
+            let! emp = x.EndOfStream 
+            return (if emp then -1 else int charBuffer.[charPos])
+        }
+
+    member x.Read() = async {
+        if (stream = null) then
+            readerClosed();
+
+        if (charPos = charLen) then 
+            let! n = readBuffer() 
+            if n = 0 then 
+                return char -1; 
+            else
+                let result = charBuffer.[charPos];
+                charPos <- charPos + 1; 
+                return result;
+        else
+            let result = charBuffer.[charPos];
+            charPos <- charPos + 1; 
+            return result;
+    }
+    
+    // Returns only when count characters have been read or the end of the file was reached. 
+    member x.ReadExactly(buffer:char[], index, count) = async {
+        let i = ref 0
+        let n = ref 0 
+        let count = ref count
+        let first = ref true
+        while !first || (!i > 0 && !n < !count) do 
+            let! j = x.Read(buffer, index + !n, !count - !n)
+            i := j 
+            n := !n + j
+            first := false
+        return !n;
+    } 
+
+    member x.Read(buffer:char[], index, count) = async {
+        if (stream = null) then
+            readerClosed(); 
+        if (buffer=null) then
+            raise <| new ArgumentNullException("buffer");
+        if (index < 0 || count < 0) then
+            raise <| new ArgumentOutOfRangeException((if (index < 0) then "index" else "count"), (* Environment.GetResourceString *)("ArgumentOutOfRange_NeedNonNegNum"));
+        if (buffer.Length - index < count) then
+            raise <| new ArgumentException("index")
+
+        let charsRead = ref 0;
+        let charsReqd = ref count;
+        let fin = ref false
+        while (!charsReqd > 0) && not !fin do
+            let! charsAvail = if (charLen = charPos) then readBuffer() else async { return charLen - charPos }
+            if (charsAvail = 0) then 
+                // We're at EOF
+                fin := true 
+            else  
+                let charsConsumed = min charsAvail !charsReqd
+                Buffer.BlockCopy(charBuffer, charPos * 2, buffer, (index + !charsRead) * 2, charsConsumed*2); 
+                charPos <- charPos + charsConsumed; 
+                charsRead := !charsRead + charsConsumed; 
+                charsReqd := !charsReqd - charsConsumed;
+
+        return !charsRead;
+    } 
+
+    member x.ReadToEnd() = async {
+        if (stream = null) then
+            readerClosed();
+
+        // Call readBuffer, then pull data out of charBuffer. 
+        let sb = new StringBuilder(charLen - charPos);
+        let readNextChunk = 
+            async {
+                sb.Append(charBuffer, charPos, charLen - charPos) |> ignore;
+                charPos <- charLen;  // Note we consumed these characters
+                let! _ = readBuffer() 
+                return ()
+            }
+        do! readNextChunk
+        while charLen > 0 do 
+            do! readNextChunk
+        return sb.ToString();
+    } 
+
+
+    // Reads a line. A line is defined as a sequence of characters followed by 
+    // a carriage return ('\r'), a line feed ('\n'), or a carriage return
+    // immediately followed by a line feed. The resulting string does not 
+    // contain the terminating carriage return and/or line feed. The returned 
+    // value is null if the end of the input stream has been reached.
+    // 
+    member x.ReadLine() = async {
+
+        let! emp = x.EndOfStream
+        if emp then return null else
+        let sb = new StringBuilder()
+        let fin1 = ref false
+        while not !fin1 do 
+            let i = ref charPos;
+            let fin2 = ref false
+            while (!i < charLen) && not !fin2 do 
+                let ch = charBuffer.[!i];
+                // Note the following common line feed chars: 
+                // \n - UNIX   \r\n - DOS   \r - Mac
+                if (ch = '\r' || ch = '\n') then
+                    sb.Append(charBuffer, charPos, !i - charPos) |> ignore; 
+                    charPos <- !i + 1; 
+                    if ch = '\r' then 
+                        let! emp = x.EndOfStream
+                        if not emp && (charBuffer.[charPos] = '\n') then 
+                            charPos <- charPos + 1;
+                    // Found end of line, done
+                    fin2 := true
+                    fin1 := true
+                else
+                    i := !i + 1;
+
+            if not !fin1 then 
+                i := charLen - charPos;
+                sb.Append(charBuffer, charPos, !i) |> ignore; 
+
+                let! n = readBuffer() 
+                fin1 := (n <= 0)
+
+        return sb.ToString(); 
+
+    }
+
--- fsharp-3.1.1.26+dfsg2.orig/FSharp.PowerPack/AsyncStreamReader.fsi
+++ fsharp-3.1.1.26+dfsg2/FSharp.PowerPack/AsyncStreamReader.fsi
@@ -1,89 +1,89 @@
-﻿namespace Microsoft.FSharp.Control
-
-open System
-open System.IO
-open System.Text
-
-/// <summary>
-/// Implements a TextReader-like API that asynchronously reads characters from 
-/// a byte stream in a particular encoding.
-/// </summary>
-[<Sealed>]
-type AsyncStreamReader =
-
-    /// Creates a new AsyncStreamReader for the given stream.  The 
-    /// character encoding is set by encoding and the buffer size,
-    /// in number of 16-bit characters, is set by bufferSize. 
-    /// 
-    /// Note that detectEncodingFromByteOrderMarks is a very
-    /// loose attempt at detecting the encoding by looking at the first 
-    /// 3 bytes of the stream.  It will recognize UTF-8, little endian
-    /// unicode, and big endian unicode text, but that's it.  If neither
-    /// of those three match, it will use the Encoding you provided.
-    new : stream:Stream * encoding:Encoding * detectEncodingFromByteOrderMarks:bool * bufferSize:int -> AsyncStreamReader
-    new : stream:Stream -> AsyncStreamReader
-    new : stream:Stream * detectEncodingFromByteOrderMarks:bool -> AsyncStreamReader
-    new : stream:Stream * encoding:System.Text.Encoding -> AsyncStreamReader
-    new : stream:Stream * encoding:System.Text.Encoding * detectEncodingFromByteOrderMarks:bool -> AsyncStreamReader
-    
-    member Close : unit -> unit
-    member CurrentEncoding : Encoding
-    member BaseStream : Stream
-    
-    ///. DiscardBufferedData tells StreamReader to throw away its internal 
-    ///. buffer contents.  This is useful if the user needs to seek on the
-    /// underlying stream to a known location then wants the StreamReader 
-    /// to start reading from this new point.  This method should be called
-    /// very sparingly, if ever, since it can lead to very poor performance.
-    /// However, it may be the only way of handling some scenarios where
-    /// users need to re-read the contents of a StreamReader a second time. 
-    member DiscardBufferedData : unit -> unit
-    
-    /// An async that produces true if the reader is at the end of stream and false otherwise
-    ///
-    /// Note that when the async is run it reflects the reader state at the time of running; multiple runs will 
-    /// yield different results.
-    member EndOfStream : Async<bool>
-    
-    /// Creates an async that produces next character from the stream without advancing the stream
-    ///
-    /// Note that when the async is run it reflects the reader state at the time of running; multiple runs will 
-    /// yield different results.
-    
-    member Peek : unit -> Async<int> 
-    
-    /// Creates an async that reads next character from the stream
-    ///
-    /// Note that when the async is run it reflects the reader state at the time of running; multiple runs will 
-    /// yield different results.
-    member Read : unit -> Async<char>
-    
-    /// Creates an async that reads all the charactes that are avilable in the stream up to <c>count</c characters and puts them 
-    /// into <c>buffer</c> starting at <c>index</c>. The async returns the number of characters that are read.
-    ///
-    /// Note that when the async is run it reflects the reader state at the time of running; multiple runs will 
-    /// yield different results.
-    member Read : buffer:char[] * index:int * count:int -> Async<int>
-    
-    /// Creates an async that reads exactly <c>count</c> characters from the stream unless end of stream is reached and puts them 
-    /// into <c>buffer</c> starting at <c>index</c>. The async returns the number of characters that are read (if end-of-stream is not reached
-    /// that will be <c>count</c>
-    ///
-    /// Note that when the async is run it reflects the reader state at the time of running; multiple runs will 
-    /// yield different results.
-    member ReadExactly : buffer:char[] * index:int * count:int -> Async<int>
-    
-    /// Creates an async that read all characters in the stream up to the end.
-    ///
-    /// Note that when the async is run it reflects the reader state at the time of running; multiple runs will 
-    /// yield different results.
-    member ReadToEnd : unit -> Async<string>
-    
-    /// Creates an async that reads next line from the stream
-    ///
-    /// Note that when the async is run it reflects the reader state at the time of running; multiple runs will 
-    /// yield different results.
-    member ReadLine : unit -> Async<string>
-    
-    interface IDisposable
+﻿namespace Microsoft.FSharp.Control
+
+open System
+open System.IO
+open System.Text
+
+/// <summary>
+/// Implements a TextReader-like API that asynchronously reads characters from 
+/// a byte stream in a particular encoding.
+/// </summary>
+[<Sealed>]
+type AsyncStreamReader =
+
+    /// Creates a new AsyncStreamReader for the given stream.  The 
+    /// character encoding is set by encoding and the buffer size,
+    /// in number of 16-bit characters, is set by bufferSize. 
+    /// 
+    /// Note that detectEncodingFromByteOrderMarks is a very
+    /// loose attempt at detecting the encoding by looking at the first 
+    /// 3 bytes of the stream.  It will recognize UTF-8, little endian
+    /// unicode, and big endian unicode text, but that's it.  If neither
+    /// of those three match, it will use the Encoding you provided.
+    new : stream:Stream * encoding:Encoding * detectEncodingFromByteOrderMarks:bool * bufferSize:int -> AsyncStreamReader
+    new : stream:Stream -> AsyncStreamReader
+    new : stream:Stream * detectEncodingFromByteOrderMarks:bool -> AsyncStreamReader
+    new : stream:Stream * encoding:System.Text.Encoding -> AsyncStreamReader
+    new : stream:Stream * encoding:System.Text.Encoding * detectEncodingFromByteOrderMarks:bool -> AsyncStreamReader
+    
+    member Close : unit -> unit
+    member CurrentEncoding : Encoding
+    member BaseStream : Stream
+    
+    ///. DiscardBufferedData tells StreamReader to throw away its internal 
+    ///. buffer contents.  This is useful if the user needs to seek on the
+    /// underlying stream to a known location then wants the StreamReader 
+    /// to start reading from this new point.  This method should be called
+    /// very sparingly, if ever, since it can lead to very poor performance.
+    /// However, it may be the only way of handling some scenarios where
+    /// users need to re-read the contents of a StreamReader a second time. 
+    member DiscardBufferedData : unit -> unit
+    
+    /// An async that produces true if the reader is at the end of stream and false otherwise
+    ///
+    /// Note that when the async is run it reflects the reader state at the time of running; multiple runs will 
+    /// yield different results.
+    member EndOfStream : Async<bool>
+    
+    /// Creates an async that produces next character from the stream without advancing the stream
+    ///
+    /// Note that when the async is run it reflects the reader state at the time of running; multiple runs will 
+    /// yield different results.
+    
+    member Peek : unit -> Async<int> 
+    
+    /// Creates an async that reads next character from the stream
+    ///
+    /// Note that when the async is run it reflects the reader state at the time of running; multiple runs will 
+    /// yield different results.
+    member Read : unit -> Async<char>
+    
+    /// Creates an async that reads all the charactes that are avilable in the stream up to <c>count</c characters and puts them 
+    /// into <c>buffer</c> starting at <c>index</c>. The async returns the number of characters that are read.
+    ///
+    /// Note that when the async is run it reflects the reader state at the time of running; multiple runs will 
+    /// yield different results.
+    member Read : buffer:char[] * index:int * count:int -> Async<int>
+    
+    /// Creates an async that reads exactly <c>count</c> characters from the stream unless end of stream is reached and puts them 
+    /// into <c>buffer</c> starting at <c>index</c>. The async returns the number of characters that are read (if end-of-stream is not reached
+    /// that will be <c>count</c>
+    ///
+    /// Note that when the async is run it reflects the reader state at the time of running; multiple runs will 
+    /// yield different results.
+    member ReadExactly : buffer:char[] * index:int * count:int -> Async<int>
+    
+    /// Creates an async that read all characters in the stream up to the end.
+    ///
+    /// Note that when the async is run it reflects the reader state at the time of running; multiple runs will 
+    /// yield different results.
+    member ReadToEnd : unit -> Async<string>
+    
+    /// Creates an async that reads next line from the stream
+    ///
+    /// Note that when the async is run it reflects the reader state at the time of running; multiple runs will 
+    /// yield different results.
+    member ReadLine : unit -> Async<string>
+    
+    interface IDisposable
     
\ No newline at end of file
--- fsharp-3.1.1.26+dfsg2.orig/FSharp.PowerPack/AsyncWorker.fs
+++ fsharp-3.1.1.26+dfsg2/FSharp.PowerPack/AsyncWorker.fs
@@ -1,65 +1,65 @@
-// (c) Microsoft Corporation 2005-2009. 
-namespace Microsoft.FSharp.Control
-
-    open System
-    open System.Threading
-    open System.IO
-    open Microsoft.FSharp.Control
-    open Microsoft.FSharp.Collections
-
-#if FX_NO_SYNC_CONTEXT
-#else
-    type AsyncWorker<'T>(p : Async<'T>,?cancellationToken) = 
-
-        let cts =
-            match cancellationToken with
-            | None -> new CancellationTokenSource()
-            | Some token ->
-                  let cts = new CancellationTokenSource()
-                  CancellationTokenSource.CreateLinkedTokenSource(token,cts.Token)
-
-        let mutable syncContext : SynchronizationContext = null
-
-        // A standard helper to raise an event on the GUI thread
-
-        let raiseEventOnGuiThread (event:Event<_>) args =
-            syncContext.Post((fun _ -> event.Trigger args),state=null)
-
-        // Trigger one of the following events when the iteration completes.
-        let completed = new Event<'T>()
-        let error     = new Event<_>()
-        let canceled   = new Event<_>()
-        let progress  = new Event<int>()
-
-        let doWork() = 
-            Async.StartWithContinuations
-                ( p, 
-                  (fun res -> raiseEventOnGuiThread completed res),
-                  (fun exn -> raiseEventOnGuiThread error exn),
-                  (fun exn -> raiseEventOnGuiThread canceled exn ),cts.Token)
-                                
-        member x.ReportProgress(progressPercentage) = 
-            raiseEventOnGuiThread progress progressPercentage
-        
-        member x.RunAsync()    = 
-            match syncContext with 
-            | null -> ()
-            | _ -> invalidOp "The operation is already in progress. RunAsync can't be called twice"
-
-            syncContext <- 
-                match SynchronizationContext.Current with 
-                | null -> new SynchronizationContext()
-                | ctxt -> ctxt
-
-            ThreadPool.QueueUserWorkItem(fun args -> doWork())
-
-        member x.CancelAsync(?message:string) = 
-            cts.Cancel()
-
-        member x.ProgressChanged     = progress.Publish
-        member x.Completed  = completed.Publish
-        member x.Canceled   = canceled.Publish
-        member x.Error      = error.Publish
-
-
-#endif
+// (c) Microsoft Corporation 2005-2009. 
+namespace Microsoft.FSharp.Control
+
+    open System
+    open System.Threading
+    open System.IO
+    open Microsoft.FSharp.Control
+    open Microsoft.FSharp.Collections
+
+#if FX_NO_SYNC_CONTEXT
+#else
+    type AsyncWorker<'T>(p : Async<'T>,?cancellationToken) = 
+
+        let cts =
+            match cancellationToken with
+            | None -> new CancellationTokenSource()
+            | Some token ->
+                  let cts = new CancellationTokenSource()
+                  CancellationTokenSource.CreateLinkedTokenSource(token,cts.Token)
+
+        let mutable syncContext : SynchronizationContext = null
+
+        // A standard helper to raise an event on the GUI thread
+
+        let raiseEventOnGuiThread (event:Event<_>) args =
+            syncContext.Post((fun _ -> event.Trigger args),state=null)
+
+        // Trigger one of the following events when the iteration completes.
+        let completed = new Event<'T>()
+        let error     = new Event<_>()
+        let canceled   = new Event<_>()
+        let progress  = new Event<int>()
+
+        let doWork() = 
+            Async.StartWithContinuations
+                ( p, 
+                  (fun res -> raiseEventOnGuiThread completed res),
+                  (fun exn -> raiseEventOnGuiThread error exn),
+                  (fun exn -> raiseEventOnGuiThread canceled exn ),cts.Token)
+                                
+        member x.ReportProgress(progressPercentage) = 
+            raiseEventOnGuiThread progress progressPercentage
+        
+        member x.RunAsync()    = 
+            match syncContext with 
+            | null -> ()
+            | _ -> invalidOp "The operation is already in progress. RunAsync can't be called twice"
+
+            syncContext <- 
+                match SynchronizationContext.Current with 
+                | null -> new SynchronizationContext()
+                | ctxt -> ctxt
+
+            ThreadPool.QueueUserWorkItem(fun args -> doWork())
+
+        member x.CancelAsync(?message:string) = 
+            cts.Cancel()
+
+        member x.ProgressChanged     = progress.Publish
+        member x.Completed  = completed.Publish
+        member x.Canceled   = canceled.Publish
+        member x.Error      = error.Publish
+
+
+#endif
--- fsharp-3.1.1.26+dfsg2.orig/FSharp.PowerPack/AsyncWorker.fsi
+++ fsharp-3.1.1.26+dfsg2/FSharp.PowerPack/AsyncWorker.fsi
@@ -1,20 +1,20 @@
-// (c) Microsoft Corporation 2005-2009.
-namespace Microsoft.FSharp.Control
-
-    open System
-    open System.Threading
-    open Microsoft.FSharp.Control
-
-#if FX_NO_SYNC_CONTEXT
-#else
-    type AsyncWorker<'T> =
-        new : Async<'T> * ?asyncGroup: CancellationToken -> AsyncWorker<'T>
-        member ProgressChanged : IEvent<int> 
-        member Error : IEvent<exn> 
-        member Completed : IEvent<'T> 
-        member Canceled : IEvent<OperationCanceledException> 
-        member RunAsync : unit -> bool
-        member ReportProgress : int -> unit
-        member CancelAsync : ?message:string -> unit
-
-#endif
+// (c) Microsoft Corporation 2005-2009.
+namespace Microsoft.FSharp.Control
+
+    open System
+    open System.Threading
+    open Microsoft.FSharp.Control
+
+#if FX_NO_SYNC_CONTEXT
+#else
+    type AsyncWorker<'T> =
+        new : Async<'T> * ?asyncGroup: CancellationToken -> AsyncWorker<'T>
+        member ProgressChanged : IEvent<int> 
+        member Error : IEvent<exn> 
+        member Completed : IEvent<'T> 
+        member Canceled : IEvent<OperationCanceledException> 
+        member RunAsync : unit -> bool
+        member ReportProgress : int -> unit
+        member CancelAsync : ?message:string -> unit
+
+#endif
--- fsharp-3.1.1.26+dfsg2.orig/FSharp.PowerPack/CompilerLocationUtils.fs
+++ fsharp-3.1.1.26+dfsg2/FSharp.PowerPack/CompilerLocationUtils.fs
@@ -1,242 +1,242 @@
-namespace Internal.Utilities
-open System
-open System.IO
-open System.Configuration
-open System.Reflection
-open Microsoft.Win32
-open System.Runtime.InteropServices
-
-#nowarn "44" // ConfigurationSettings is obsolete but the new stuff is horribly complicated. 
-
-module internal FSharpEnvironment =
-
-    let FSharpCoreLibRunningVersion = 
-        try match (typeof<Microsoft.FSharp.Collections.List<int>>).Assembly.GetName().Version.ToString() with
-            | null -> None
-            | "" -> None
-            | s  -> Some(s)
-        with _ -> None
-
-    // Returns:
-    // -- on 2.0:  "v2.0.50727"
-    // -- on 4.0:  "v4.0.30109" (last 5 digits vary by build)
-    let MSCorLibRunningRuntimeVersion = 
-        typeof<int>.Assembly.ImageRuntimeVersion
-
-    // The F# team version number. This version number is used for
-    //     - the F# version number reported by the fsc.exe and fsi.exe banners in the CTP release
-    //     - the F# version number printed in the HTML documentation generator
-    //     - the .NET DLL version number for all VS2008 DLLs
-    //     - the VS2008 registry key, written by the VS2008 installer
-    //         HKEY_LOCAL_MACHINE\Software\Microsoft\.NETFramework\AssemblyFolders\Microsoft.FSharp-" + FSharpTeamVersionNumber
-    // Also
-    //     - for Beta2, the language revision number indicated on the F# language spec
-    //
-    // It is NOT the version number listed on FSharp.Core.dll
-    let FSharpTeamVersionNumber = "1.9.9.9"
-
-    // The F# binary format revision number. The first three digits of this form the significant part of the 
-    // format revision number for F# binary signature and optimization metadata. The last digit is not significant.
-    //
-    // WARNING: Do not change this revision number unless you absolutely know what you're doing.
-    let FSharpBinaryMetadataFormatRevision = "2.0.0.0"
-
-    [<DllImport("Advapi32.dll", CharSet = CharSet.Unicode, BestFitMapping = false)>]
-    extern uint32 RegOpenKeyExW(UIntPtr _hKey, string _lpSubKey, uint32 _ulOptions, int _samDesired, UIntPtr & _phkResult);
-
-    [<DllImport("Advapi32.dll", CharSet = CharSet.Unicode, BestFitMapping = false)>]
-    extern uint32 RegQueryValueExW(UIntPtr _hKey, string _lpValueName, uint32 _lpReserved, uint32 & _lpType, IntPtr _lpData, int & _lpchData);
-
-    [<DllImport("Advapi32.dll")>]
-    extern uint32 RegCloseKey(UIntPtr _hKey)
-
-    module Option = 
-        /// Convert string into Option string where null and String.Empty result in None
-        let ofString s = 
-            if String.IsNullOrEmpty(s) then None
-            else Some(s)
-
-            
-        
-
-    // MaxPath accounts for the null-terminating character, for example, the maximum path on the D drive is "D:\<256 chars>\0". 
-    // See: ndp\clr\src\BCL\System\IO\Path.cs
-    let maxPath = 260;
-    let maxDataLength = (new System.Text.UTF32Encoding()).GetMaxByteCount(maxPath)
-    let KEY_WOW64_DEFAULT = 0x0000
-    let KEY_WOW64_32KEY = 0x0200
-    let HKEY_LOCAL_MACHINE = UIntPtr(0x80000002u)
-    let KEY_QUERY_VALUE = 0x1
-    let REG_SZ = 1u
-
-    let GetDefaultRegistryStringValueViaDotNet(subKey: string)  =
-        Option.ofString
-            (try
-                downcast Microsoft.Win32.Registry.GetValue("HKEY_LOCAL_MACHINE\\"+subKey,null,null)
-             with e->
-                System.Diagnostics.Debug.Assert(false, sprintf "Failed in GetDefaultRegistryStringValueViaDotNet: %s" (e.ToString()))
-                null)
-
-    let Get32BitRegistryStringValueViaPInvoke(subKey:string) = 
-        Option.ofString
-            (try 
-                // 64 bit flag is not available <= Win2k
-                let options = 
-                    match Environment.OSVersion.Version.Major with
-                    | major when major >= 5 -> KEY_WOW64_32KEY
-                    | _ -> KEY_WOW64_DEFAULT
-
-
-                let mutable hkey = UIntPtr.Zero;
-                let pathResult = Marshal.AllocCoTaskMem(maxDataLength);
-
-                try
-                    let res = RegOpenKeyExW(HKEY_LOCAL_MACHINE,subKey, 0u, KEY_QUERY_VALUE ||| options, & hkey)
-                    if res = 0u then
-                        let mutable uType = REG_SZ;
-                        let mutable cbData = maxDataLength;
-
-                        let res = RegQueryValueExW(hkey, null, 0u, &uType, pathResult, &cbData);
-
-                        if (res = 0u && cbData > 0 && cbData <= maxDataLength) then
-                            Marshal.PtrToStringUni(pathResult, (cbData - 2)/2);
-                        else 
-                            null
-                    else
-                        null
-                finally
-                    if hkey <> UIntPtr.Zero then
-                        RegCloseKey(hkey) |> ignore
-                
-                    if pathResult <> IntPtr.Zero then
-                        Marshal.FreeCoTaskMem(pathResult)
-             with e->
-                System.Diagnostics.Debug.Assert(false, sprintf "Failed in Get32BitRegistryStringValueViaPInvoke: %s" (e.ToString()))
-                null)
-
-    let is32Bit = IntPtr.Size = 4
-    
-    let tryRegKey(subKey:string) = 
-
-        if is32Bit then
-            let s = GetDefaultRegistryStringValueViaDotNet(subKey)
-            // If we got here AND we're on a 32-bit OS then we can validate that Get32BitRegistryStringValueViaPInvoke(...) works
-            // by comparing against the result from GetDefaultRegistryStringValueViaDotNet(...)
-#if DEBUG
-            let viaPinvoke = Get32BitRegistryStringValueViaPInvoke(subKey)
-            System.Diagnostics.Debug.Assert((s = viaPinvoke), sprintf "32bit path: pi=%A def=%A" viaPinvoke s)
-#endif
-            s
-        else
-            Get32BitRegistryStringValueViaPInvoke(subKey) 
-               
-
-    let internal tryCurrentDomain() = 
-        let pathFromCurrentDomain = System.AppDomain.CurrentDomain.BaseDirectory
-        if not(String.IsNullOrEmpty(pathFromCurrentDomain)) then 
-            Some pathFromCurrentDomain
-        else
-            None
-    
-    let internal tryAppConfig (appConfigKey:string) = 
-
-        let locationFromAppConfig = ConfigurationSettings.AppSettings.[appConfigKey]
-        System.Diagnostics.Debug.Print(sprintf "Considering appConfigKey %s which has value '%s'" appConfigKey locationFromAppConfig) 
-
-        if String.IsNullOrEmpty(locationFromAppConfig) then 
-            None
-        else
-            let exeAssemblyFolder = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location)
-            let locationFromAppConfig = locationFromAppConfig.Replace("{exepath}", exeAssemblyFolder)
-            System.Diagnostics.Debug.Print(sprintf "Using path %s" locationFromAppConfig) 
-            Some locationFromAppConfig
-
-    let BinFolderOfDefaultFSharpCoreReferenceAssembly = 
-        try
-            let result = tryAppConfig "fsharp-core-referenceassembly-location"
-            match result with
-            | Some _ -> result
-            | None ->
-                let keyCTP = @"Software\Microsoft\.NETFramework\AssemblyFolders\Microsoft.FSharp-" + FSharpTeamVersionNumber 
-                let keyRedist = @"SOFTWARE\Microsoft\.NETFramework\" + MSCorLibRunningRuntimeVersion + @"\AssemblyFoldersEx\Microsoft Visual F# 4.0"
-                
-                let result = tryRegKey keyRedist
-                match result with 
-                | Some _ ->  result 
-                | None -> 
-                    let result = tryRegKey keyCTP
-                    match result with
-                    | Some _ -> result
-                    | None -> 
-                        tryCurrentDomain ()
-
-        with e -> 
-            System.Diagnostics.Debug.Assert(false, "Error while determining default location of FSharp.Core reference assembly")
-            None
-
-    // The default location of FSharp.Core.dll and fsc.exe based on the version of fsc.exe that is running
-    // Used for
-    //     - location of design-time copies of FSharp.Core.dll and FSharp.Compiler.Interactive.Settings.dll for the default assumed environment for scripts
-    //     - default ToolPath in tasks in FSharp.Build.dll (for Fsc tasks)
-    //     - default F# binaries directory in service.fs (REVIEW: check this)
-    //     - default location of fsi.exe in FSharp.VS.FSI.dll
-    //     - default location of fsc.exe in FSharp.Compiler.CodeDom.dll
-    let BinFolderOfDefaultFSharpCompiler = 
-        // Check for an app.config setting to redirect the default compiler location
-        // Like fsharp-compiler-location
-        try 
-            let result = tryAppConfig "fsharp-compiler-location"
-            match result with 
-            | Some _ ->  result 
-            | None -> 
-
-                // Note: If the keys below change, be sure to update code in:
-                // Property pages (ApplicationPropPage.vb)
-
-                let key20 = @"Software\Microsoft\.NETFramework\AssemblyFolders\Microsoft.FSharp-" + FSharpTeamVersionNumber 
-                let key40 = @"Software\Microsoft\FSharp\2.0\Runtime\v4.0"
-                let key1,key2 = 
-                    match FSharpCoreLibRunningVersion with 
-                    | None -> key20,key40 
-                    | Some v -> if v.Length > 1 && v.[0] <= '3' then key20,key40 else key40,key20
-                
-                let result = tryRegKey key1
-                match result with 
-                | Some _ ->  result 
-                | None -> 
-                    let result =  tryRegKey key2
-                    match result with 
-                    | Some _ ->  result 
-                    | None -> 
-
-            // This was failing on rolling build for staging because the prototype compiler doesn't have the key. Disable there.
-            #if FX_ATLEAST_40_COMPILER_LOCATION
-                        System.Diagnostics.Debug.Assert(result<>None, sprintf "Could not find location of compiler at '%s' or '%s'" key1 key2)
-            #endif                                
-                          
-                            // For the prototype compiler, we can just use the current domain
-                        tryCurrentDomain()
-        with e -> 
-            System.Diagnostics.Debug.Assert(false, "Error while determining default location of F# compiler")
-            None
-
-    let BinFolderOfFSharpPowerPack = 
-        try 
-            // Check for an app.config setting to redirect the default compiler location
-            // Like fsharp-compiler-location
-            let result = tryAppConfig "fsharp-powerpack-location"
-            match result with 
-            | Some _ ->  result 
-            | None -> 
-
-                let key20 = @"Software\Microsoft\.NETFramework\AssemblyFolders\FSharp.PowerPack-" + FSharpTeamVersionNumber 
-                let result = tryRegKey key20
-                match result with 
-                | Some _ ->  result 
-                | None -> 
-                      
-                    tryCurrentDomain()
-
-        with e -> 
-            System.Diagnostics.Debug.Assert(false, "Error while determining default location of F# power pack tools")
-            None
+namespace Internal.Utilities
+open System
+open System.IO
+open System.Configuration
+open System.Reflection
+open Microsoft.Win32
+open System.Runtime.InteropServices
+
+#nowarn "44" // ConfigurationSettings is obsolete but the new stuff is horribly complicated. 
+
+module internal FSharpEnvironment =
+
+    let FSharpCoreLibRunningVersion = 
+        try match (typeof<Microsoft.FSharp.Collections.List<int>>).Assembly.GetName().Version.ToString() with
+            | null -> None
+            | "" -> None
+            | s  -> Some(s)
+        with _ -> None
+
+    // Returns:
+    // -- on 2.0:  "v2.0.50727"
+    // -- on 4.0:  "v4.0.30109" (last 5 digits vary by build)
+    let MSCorLibRunningRuntimeVersion = 
+        typeof<int>.Assembly.ImageRuntimeVersion
+
+    // The F# team version number. This version number is used for
+    //     - the F# version number reported by the fsc.exe and fsi.exe banners in the CTP release
+    //     - the F# version number printed in the HTML documentation generator
+    //     - the .NET DLL version number for all VS2008 DLLs
+    //     - the VS2008 registry key, written by the VS2008 installer
+    //         HKEY_LOCAL_MACHINE\Software\Microsoft\.NETFramework\AssemblyFolders\Microsoft.FSharp-" + FSharpTeamVersionNumber
+    // Also
+    //     - for Beta2, the language revision number indicated on the F# language spec
+    //
+    // It is NOT the version number listed on FSharp.Core.dll
+    let FSharpTeamVersionNumber = "1.9.9.9"
+
+    // The F# binary format revision number. The first three digits of this form the significant part of the 
+    // format revision number for F# binary signature and optimization metadata. The last digit is not significant.
+    //
+    // WARNING: Do not change this revision number unless you absolutely know what you're doing.
+    let FSharpBinaryMetadataFormatRevision = "2.0.0.0"
+
+    [<DllImport("Advapi32.dll", CharSet = CharSet.Unicode, BestFitMapping = false)>]
+    extern uint32 RegOpenKeyExW(UIntPtr _hKey, string _lpSubKey, uint32 _ulOptions, int _samDesired, UIntPtr & _phkResult);
+
+    [<DllImport("Advapi32.dll", CharSet = CharSet.Unicode, BestFitMapping = false)>]
+    extern uint32 RegQueryValueExW(UIntPtr _hKey, string _lpValueName, uint32 _lpReserved, uint32 & _lpType, IntPtr _lpData, int & _lpchData);
+
+    [<DllImport("Advapi32.dll")>]
+    extern uint32 RegCloseKey(UIntPtr _hKey)
+
+    module Option = 
+        /// Convert string into Option string where null and String.Empty result in None
+        let ofString s = 
+            if String.IsNullOrEmpty(s) then None
+            else Some(s)
+
+            
+        
+
+    // MaxPath accounts for the null-terminating character, for example, the maximum path on the D drive is "D:\<256 chars>\0". 
+    // See: ndp\clr\src\BCL\System\IO\Path.cs
+    let maxPath = 260;
+    let maxDataLength = (new System.Text.UTF32Encoding()).GetMaxByteCount(maxPath)
+    let KEY_WOW64_DEFAULT = 0x0000
+    let KEY_WOW64_32KEY = 0x0200
+    let HKEY_LOCAL_MACHINE = UIntPtr(0x80000002u)
+    let KEY_QUERY_VALUE = 0x1
+    let REG_SZ = 1u
+
+    let GetDefaultRegistryStringValueViaDotNet(subKey: string)  =
+        Option.ofString
+            (try
+                downcast Microsoft.Win32.Registry.GetValue("HKEY_LOCAL_MACHINE\\"+subKey,null,null)
+             with e->
+                System.Diagnostics.Debug.Assert(false, sprintf "Failed in GetDefaultRegistryStringValueViaDotNet: %s" (e.ToString()))
+                null)
+
+    let Get32BitRegistryStringValueViaPInvoke(subKey:string) = 
+        Option.ofString
+            (try 
+                // 64 bit flag is not available <= Win2k
+                let options = 
+                    match Environment.OSVersion.Version.Major with
+                    | major when major >= 5 -> KEY_WOW64_32KEY
+                    | _ -> KEY_WOW64_DEFAULT
+
+
+                let mutable hkey = UIntPtr.Zero;
+                let pathResult = Marshal.AllocCoTaskMem(maxDataLength);
+
+                try
+                    let res = RegOpenKeyExW(HKEY_LOCAL_MACHINE,subKey, 0u, KEY_QUERY_VALUE ||| options, & hkey)
+                    if res = 0u then
+                        let mutable uType = REG_SZ;
+                        let mutable cbData = maxDataLength;
+
+                        let res = RegQueryValueExW(hkey, null, 0u, &uType, pathResult, &cbData);
+
+                        if (res = 0u && cbData > 0 && cbData <= maxDataLength) then
+                            Marshal.PtrToStringUni(pathResult, (cbData - 2)/2);
+                        else 
+                            null
+                    else
+                        null
+                finally
+                    if hkey <> UIntPtr.Zero then
+                        RegCloseKey(hkey) |> ignore
+                
+                    if pathResult <> IntPtr.Zero then
+                        Marshal.FreeCoTaskMem(pathResult)
+             with e->
+                System.Diagnostics.Debug.Assert(false, sprintf "Failed in Get32BitRegistryStringValueViaPInvoke: %s" (e.ToString()))
+                null)
+
+    let is32Bit = IntPtr.Size = 4
+    
+    let tryRegKey(subKey:string) = 
+
+        if is32Bit then
+            let s = GetDefaultRegistryStringValueViaDotNet(subKey)
+            // If we got here AND we're on a 32-bit OS then we can validate that Get32BitRegistryStringValueViaPInvoke(...) works
+            // by comparing against the result from GetDefaultRegistryStringValueViaDotNet(...)
+#if DEBUG
+            let viaPinvoke = Get32BitRegistryStringValueViaPInvoke(subKey)
+            System.Diagnostics.Debug.Assert((s = viaPinvoke), sprintf "32bit path: pi=%A def=%A" viaPinvoke s)
+#endif
+            s
+        else
+            Get32BitRegistryStringValueViaPInvoke(subKey) 
+               
+
+    let internal tryCurrentDomain() = 
+        let pathFromCurrentDomain = System.AppDomain.CurrentDomain.BaseDirectory
+        if not(String.IsNullOrEmpty(pathFromCurrentDomain)) then 
+            Some pathFromCurrentDomain
+        else
+            None
+    
+    let internal tryAppConfig (appConfigKey:string) = 
+
+        let locationFromAppConfig = ConfigurationSettings.AppSettings.[appConfigKey]
+        System.Diagnostics.Debug.Print(sprintf "Considering appConfigKey %s which has value '%s'" appConfigKey locationFromAppConfig) 
+
+        if String.IsNullOrEmpty(locationFromAppConfig) then 
+            None
+        else
+            let exeAssemblyFolder = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location)
+            let locationFromAppConfig = locationFromAppConfig.Replace("{exepath}", exeAssemblyFolder)
+            System.Diagnostics.Debug.Print(sprintf "Using path %s" locationFromAppConfig) 
+            Some locationFromAppConfig
+
+    let BinFolderOfDefaultFSharpCoreReferenceAssembly = 
+        try
+            let result = tryAppConfig "fsharp-core-referenceassembly-location"
+            match result with
+            | Some _ -> result
+            | None ->
+                let keyCTP = @"Software\Microsoft\.NETFramework\AssemblyFolders\Microsoft.FSharp-" + FSharpTeamVersionNumber 
+                let keyRedist = @"SOFTWARE\Microsoft\.NETFramework\" + MSCorLibRunningRuntimeVersion + @"\AssemblyFoldersEx\Microsoft Visual F# 4.0"
+                
+                let result = tryRegKey keyRedist
+                match result with 
+                | Some _ ->  result 
+                | None -> 
+                    let result = tryRegKey keyCTP
+                    match result with
+                    | Some _ -> result
+                    | None -> 
+                        tryCurrentDomain ()
+
+        with e -> 
+            System.Diagnostics.Debug.Assert(false, "Error while determining default location of FSharp.Core reference assembly")
+            None
+
+    // The default location of FSharp.Core.dll and fsc.exe based on the version of fsc.exe that is running
+    // Used for
+    //     - location of design-time copies of FSharp.Core.dll and FSharp.Compiler.Interactive.Settings.dll for the default assumed environment for scripts
+    //     - default ToolPath in tasks in FSharp.Build.dll (for Fsc tasks)
+    //     - default F# binaries directory in service.fs (REVIEW: check this)
+    //     - default location of fsi.exe in FSharp.VS.FSI.dll
+    //     - default location of fsc.exe in FSharp.Compiler.CodeDom.dll
+    let BinFolderOfDefaultFSharpCompiler = 
+        // Check for an app.config setting to redirect the default compiler location
+        // Like fsharp-compiler-location
+        try 
+            let result = tryAppConfig "fsharp-compiler-location"
+            match result with 
+            | Some _ ->  result 
+            | None -> 
+
+                // Note: If the keys below change, be sure to update code in:
+                // Property pages (ApplicationPropPage.vb)
+
+                let key20 = @"Software\Microsoft\.NETFramework\AssemblyFolders\Microsoft.FSharp-" + FSharpTeamVersionNumber 
+                let key40 = @"Software\Microsoft\FSharp\2.0\Runtime\v4.0"
+                let key1,key2 = 
+                    match FSharpCoreLibRunningVersion with 
+                    | None -> key20,key40 
+                    | Some v -> if v.Length > 1 && v.[0] <= '3' then key20,key40 else key40,key20
+                
+                let result = tryRegKey key1
+                match result with 
+                | Some _ ->  result 
+                | None -> 
+                    let result =  tryRegKey key2
+                    match result with 
+                    | Some _ ->  result 
+                    | None -> 
+
+            // This was failing on rolling build for staging because the prototype compiler doesn't have the key. Disable there.
+            #if FX_ATLEAST_40_COMPILER_LOCATION
+                        System.Diagnostics.Debug.Assert(result<>None, sprintf "Could not find location of compiler at '%s' or '%s'" key1 key2)
+            #endif                                
+                          
+                            // For the prototype compiler, we can just use the current domain
+                        tryCurrentDomain()
+        with e -> 
+            System.Diagnostics.Debug.Assert(false, "Error while determining default location of F# compiler")
+            None
+
+    let BinFolderOfFSharpPowerPack = 
+        try 
+            // Check for an app.config setting to redirect the default compiler location
+            // Like fsharp-compiler-location
+            let result = tryAppConfig "fsharp-powerpack-location"
+            match result with 
+            | Some _ ->  result 
+            | None -> 
+
+                let key20 = @"Software\Microsoft\.NETFramework\AssemblyFolders\FSharp.PowerPack-" + FSharpTeamVersionNumber 
+                let result = tryRegKey key20
+                match result with 
+                | Some _ ->  result 
+                | None -> 
+                      
+                    tryCurrentDomain()
+
+        with e -> 
+            System.Diagnostics.Debug.Assert(false, "Error while determining default location of F# power pack tools")
+            None
--- fsharp-3.1.1.26+dfsg2.orig/FSharp.PowerPack/FSharp.PowerPack.fsproj.vspscc
+++ fsharp-3.1.1.26+dfsg2/FSharp.PowerPack/FSharp.PowerPack.fsproj.vspscc
@@ -1,10 +1,10 @@
-﻿""
-{
-"FILE_VERSION" = "9237"
-"ENLISTMENT_CHOICE" = "NEVER"
-"PROJECT_FILE_RELATIVE_PATH" = ""
-"NUMBER_OF_EXCLUDED_FILES" = "0"
-"ORIGINAL_PROJECT_FILE_PATH" = ""
-"NUMBER_OF_NESTED_PROJECTS" = "0"
-"SOURCE_CONTROL_SETTINGS_PROVIDER" = "PROVIDER"
-}
+﻿""
+{
+"FILE_VERSION" = "9237"
+"ENLISTMENT_CHOICE" = "NEVER"
+"PROJECT_FILE_RELATIVE_PATH" = ""
+"NUMBER_OF_EXCLUDED_FILES" = "0"
+"ORIGINAL_PROJECT_FILE_PATH" = ""
+"NUMBER_OF_NESTED_PROJECTS" = "0"
+"SOURCE_CONTROL_SETTINGS_PROVIDER" = "PROVIDER"
+}
--- fsharp-3.1.1.26+dfsg2.orig/FSharp.PowerPack/HashMultiMap.fs
+++ fsharp-3.1.1.26+dfsg2/FSharp.PowerPack/HashMultiMap.fs
@@ -1,166 +1,166 @@
-// (c) Microsoft Corporation 2005-2009. 
-
-
-namespace Microsoft.FSharp.Collections
-
-open System
-open System.Collections.Generic
-open Microsoft.FSharp.Collections
-                                 
-// Each entry in the HashMultiMap dictionary has at least one entry. Under normal usage each entry has _only_
-// one entry. So use two hash tables: one for the main entries and one for the overflow.
-[<Sealed>]
-type HashMultiMap<'Key,'Value>(n: int, hasheq: IEqualityComparer<'Key>) = 
-    let firstEntries = new Dictionary<_,_>(n,hasheq);
-    let rest = new Dictionary<_,_>(3,hasheq);
- 
-    new (hasheq : IEqualityComparer<'Key>) = new HashMultiMap<'Key,'Value>(11, hasheq)
-    new (seq : seq<'Key * 'Value>, hasheq : IEqualityComparer<'Key>) as x = 
-        new HashMultiMap<'Key,'Value>(11, hasheq)
-        then seq |> Seq.iter (fun (k,v) -> x.Add(k,v))
-
-    new (seq : seq<'Key * 'Value>) =  failwith "unreachable: obsolete and error"; new HashMultiMap<'Key,'Value>()
-    new (n:int) = failwith "unreachable: obsolete and error"; new HashMultiMap<'Key,'Value>()
-    new () = failwith "unreachable: obsolete and error"; new HashMultiMap<'Key,'Value>()
-
-    static member Create (seq : seq<'Key * 'Value>) =  failwith "unreachable: obsolete and error"; new HashMultiMap<'Key,'Value>()
-    static member Create (n:int) = failwith "unreachable: obsolete and error"; new HashMultiMap<'Key,'Value>()
-    static member Create () = failwith "unreachable: obsolete and error"; new HashMultiMap<'Key,'Value>()
-
-
-    member x.GetRest(k) = 
-        let mutable res = []
-        let ok = rest.TryGetValue(k,&res)
-        if ok then res else []
-
-    member x.Add(y,z) = 
-        let mutable res = Unchecked.defaultof<'Value>
-        let ok = firstEntries.TryGetValue(y,&res)
-        if ok then 
-            rest.[y] <- res :: x.GetRest(y)
-        firstEntries.[y] <- z
-
-    member x.Clear() = 
-         firstEntries.Clear()
-         rest.Clear()
-
-    member x.FirstEntries = firstEntries
-    member x.Rest = rest
-    member x.Copy() = 
-        let res = new HashMultiMap<'Key,'Value>(firstEntries.Count,firstEntries.Comparer) 
-        for kvp in firstEntries do 
-             res.FirstEntries.Add(kvp.Key,kvp.Value)
-        for kvp in rest do 
-             res.Rest.Add(kvp.Key,kvp.Value)
-        res
-
-    member x.Item 
-        with get(y : 'Key) = 
-            let mutable res = Unchecked.defaultof<'Value>
-            let ok = firstEntries.TryGetValue(y,&res)
-            if ok then res else raise (new System.Collections.Generic.KeyNotFoundException("The item was not found in collection"))
-        and set (y:'Key) (z:'Value) = 
-            x.Replace(y,z)
-
-    member x.FindAll(y) = 
-        let mutable res = Unchecked.defaultof<'Value>
-        let ok = firstEntries.TryGetValue(y,&res)
-        if ok then res :: x.GetRest(y) else []
-
-    member x.Fold f acc = 
-        let mutable res = acc
-        for kvp in firstEntries do
-            res <- f kvp.Key kvp.Value res
-            match x.GetRest(kvp.Key)  with
-            | [] -> ()
-            | rest -> 
-                for z in rest do
-                    res <- f kvp.Key z res
-        res
-
-    member x.Iterate(f) =  
-        for kvp in firstEntries do
-            f kvp.Key kvp.Value
-            match x.GetRest(kvp.Key)  with
-            | [] -> ()
-            | rest -> 
-                for z in rest do
-                    f kvp.Key z
-
-    member x.Contains(y) = firstEntries.ContainsKey(y)
-
-    member x.ContainsKey(y) = firstEntries.ContainsKey(y)
-
-    member x.Remove(y) = 
-        let mutable res = Unchecked.defaultof<'Value>
-        let ok = firstEntries.TryGetValue(y,&res)
-        // Note, if not ok then nothing to remove - nop
-        if ok then 
-            // We drop the FirstEntry. Here we compute the new FirstEntry and residue MoreEntries
-            let mutable res = []
-            let ok = rest.TryGetValue(y,&res)
-            if ok then 
-                match res with 
-                | [h] -> 
-                    firstEntries.[y] <- h; 
-                    rest.Remove(y) |> ignore
-                | (h::t) -> 
-                    firstEntries.[y] <- h
-                    rest.[y] <- t
-                | _ -> 
-                    // note: broken invariant
-                    ()
-            else
-                firstEntries.Remove(y) |> ignore 
-
-    member x.Replace(y,z) = 
-        firstEntries.[y] <- z
-
-    member x.TryFind(y) = 
-        let mutable res = Unchecked.defaultof<'Value>
-        let ok = firstEntries.TryGetValue(y,&res)
-        if ok then Some(res) else None
-
-    member x.Count = firstEntries.Count
-
-    interface IEnumerable<KeyValuePair<'Key, 'Value>> with
-        member s.GetEnumerator() = 
-            let elems = new System.Collections.Generic.List<_>(firstEntries.Count + rest.Count)
-            for kvp in firstEntries do
-                elems.Add(kvp)
-                for z in s.GetRest(kvp.Key) do
-                   elems.Add(KeyValuePair(kvp.Key, z))
-            (elems.GetEnumerator() :> IEnumerator<_>)
-
-    interface System.Collections.IEnumerable with
-        member s.GetEnumerator() = ((s :> seq<_>).GetEnumerator() :> System.Collections.IEnumerator)
-
-    interface IDictionary<'Key, 'Value> with 
-        member s.Item 
-            with get x = s.[x]            
-            and  set x v = s.[x] <- v
-            
-        member s.Keys = ([| for kvp in s -> kvp.Key |] :> ICollection<'Key>)
-        member s.Values = ([| for kvp in s -> kvp.Value |] :> ICollection<'Value>)
-        member s.Add(k,v) = s.[k] <- v
-        member s.ContainsKey(k) = s.ContainsKey(k)
-        member s.TryGetValue(k,r) = if s.ContainsKey(k) then (r <- s.[k]; true) else false
-        member s.Remove(k:'Key) = 
-            let res = s.ContainsKey(k) in 
-            s.Remove(k); res
-
-    interface ICollection<KeyValuePair<'Key, 'Value>> with 
-        member s.Add(x) = s.[x.Key] <- x.Value
-        member s.Clear() = s.Clear()            
-        member s.Remove(x) = 
-            let res = s.ContainsKey(x.Key) 
-            if res && Unchecked.equals s.[x.Key] x.Value then 
-                s.Remove(x.Key); 
-            res
-        member s.Contains(x) = 
-            s.ContainsKey(x.Key) && 
-            Unchecked.equals s.[x.Key] x.Value
-        member s.CopyTo(arr,arrIndex) = s |> Seq.iteri (fun j x -> arr.[arrIndex+j] <- x)
-        member s.IsReadOnly = false
-        member s.Count = s.Count
-
+// (c) Microsoft Corporation 2005-2009. 
+
+
+namespace Microsoft.FSharp.Collections
+
+open System
+open System.Collections.Generic
+open Microsoft.FSharp.Collections
+                                 
+// Each entry in the HashMultiMap dictionary has at least one entry. Under normal usage each entry has _only_
+// one entry. So use two hash tables: one for the main entries and one for the overflow.
+[<Sealed>]
+type HashMultiMap<'Key,'Value>(n: int, hasheq: IEqualityComparer<'Key>) = 
+    let firstEntries = new Dictionary<_,_>(n,hasheq);
+    let rest = new Dictionary<_,_>(3,hasheq);
+ 
+    new (hasheq : IEqualityComparer<'Key>) = new HashMultiMap<'Key,'Value>(11, hasheq)
+    new (seq : seq<'Key * 'Value>, hasheq : IEqualityComparer<'Key>) as x = 
+        new HashMultiMap<'Key,'Value>(11, hasheq)
+        then seq |> Seq.iter (fun (k,v) -> x.Add(k,v))
+
+    new (seq : seq<'Key * 'Value>) =  failwith "unreachable: obsolete and error"; new HashMultiMap<'Key,'Value>()
+    new (n:int) = failwith "unreachable: obsolete and error"; new HashMultiMap<'Key,'Value>()
+    new () = failwith "unreachable: obsolete and error"; new HashMultiMap<'Key,'Value>()
+
+    static member Create (seq : seq<'Key * 'Value>) =  failwith "unreachable: obsolete and error"; new HashMultiMap<'Key,'Value>()
+    static member Create (n:int) = failwith "unreachable: obsolete and error"; new HashMultiMap<'Key,'Value>()
+    static member Create () = failwith "unreachable: obsolete and error"; new HashMultiMap<'Key,'Value>()
+
+
+    member x.GetRest(k) = 
+        let mutable res = []
+        let ok = rest.TryGetValue(k,&res)
+        if ok then res else []
+
+    member x.Add(y,z) = 
+        let mutable res = Unchecked.defaultof<'Value>
+        let ok = firstEntries.TryGetValue(y,&res)
+        if ok then 
+            rest.[y] <- res :: x.GetRest(y)
+        firstEntries.[y] <- z
+
+    member x.Clear() = 
+         firstEntries.Clear()
+         rest.Clear()
+
+    member x.FirstEntries = firstEntries
+    member x.Rest = rest
+    member x.Copy() = 
+        let res = new HashMultiMap<'Key,'Value>(firstEntries.Count,firstEntries.Comparer) 
+        for kvp in firstEntries do 
+             res.FirstEntries.Add(kvp.Key,kvp.Value)
+        for kvp in rest do 
+             res.Rest.Add(kvp.Key,kvp.Value)
+        res
+
+    member x.Item 
+        with get(y : 'Key) = 
+            let mutable res = Unchecked.defaultof<'Value>
+            let ok = firstEntries.TryGetValue(y,&res)
+            if ok then res else raise (new System.Collections.Generic.KeyNotFoundException("The item was not found in collection"))
+        and set (y:'Key) (z:'Value) = 
+            x.Replace(y,z)
+
+    member x.FindAll(y) = 
+        let mutable res = Unchecked.defaultof<'Value>
+        let ok = firstEntries.TryGetValue(y,&res)
+        if ok then res :: x.GetRest(y) else []
+
+    member x.Fold f acc = 
+        let mutable res = acc
+        for kvp in firstEntries do
+            res <- f kvp.Key kvp.Value res
+            match x.GetRest(kvp.Key)  with
+            | [] -> ()
+            | rest -> 
+                for z in rest do
+                    res <- f kvp.Key z res
+        res
+
+    member x.Iterate(f) =  
+        for kvp in firstEntries do
+            f kvp.Key kvp.Value
+            match x.GetRest(kvp.Key)  with
+            | [] -> ()
+            | rest -> 
+                for z in rest do
+                    f kvp.Key z
+
+    member x.Contains(y) = firstEntries.ContainsKey(y)
+
+    member x.ContainsKey(y) = firstEntries.ContainsKey(y)
+
+    member x.Remove(y) = 
+        let mutable res = Unchecked.defaultof<'Value>
+        let ok = firstEntries.TryGetValue(y,&res)
+        // Note, if not ok then nothing to remove - nop
+        if ok then 
+            // We drop the FirstEntry. Here we compute the new FirstEntry and residue MoreEntries
+            let mutable res = []
+            let ok = rest.TryGetValue(y,&res)
+            if ok then 
+                match res with 
+                | [h] -> 
+                    firstEntries.[y] <- h; 
+                    rest.Remove(y) |> ignore
+                | (h::t) -> 
+                    firstEntries.[y] <- h
+                    rest.[y] <- t
+                | _ -> 
+                    // note: broken invariant
+                    ()
+            else
+                firstEntries.Remove(y) |> ignore 
+
+    member x.Replace(y,z) = 
+        firstEntries.[y] <- z
+
+    member x.TryFind(y) = 
+        let mutable res = Unchecked.defaultof<'Value>
+        let ok = firstEntries.TryGetValue(y,&res)
+        if ok then Some(res) else None
+
+    member x.Count = firstEntries.Count
+
+    interface IEnumerable<KeyValuePair<'Key, 'Value>> with
+        member s.GetEnumerator() = 
+            let elems = new System.Collections.Generic.List<_>(firstEntries.Count + rest.Count)
+            for kvp in firstEntries do
+                elems.Add(kvp)
+                for z in s.GetRest(kvp.Key) do
+                   elems.Add(KeyValuePair(kvp.Key, z))
+            (elems.GetEnumerator() :> IEnumerator<_>)
+
+    interface System.Collections.IEnumerable with
+        member s.GetEnumerator() = ((s :> seq<_>).GetEnumerator() :> System.Collections.IEnumerator)
+
+    interface IDictionary<'Key, 'Value> with 
+        member s.Item 
+            with get x = s.[x]            
+            and  set x v = s.[x] <- v
+            
+        member s.Keys = ([| for kvp in s -> kvp.Key |] :> ICollection<'Key>)
+        member s.Values = ([| for kvp in s -> kvp.Value |] :> ICollection<'Value>)
+        member s.Add(k,v) = s.[k] <- v
+        member s.ContainsKey(k) = s.ContainsKey(k)
+        member s.TryGetValue(k,r) = if s.ContainsKey(k) then (r <- s.[k]; true) else false
+        member s.Remove(k:'Key) = 
+            let res = s.ContainsKey(k) in 
+            s.Remove(k); res
+
+    interface ICollection<KeyValuePair<'Key, 'Value>> with 
+        member s.Add(x) = s.[x.Key] <- x.Value
+        member s.Clear() = s.Clear()            
+        member s.Remove(x) = 
+            let res = s.ContainsKey(x.Key) 
+            if res && Unchecked.equals s.[x.Key] x.Value then 
+                s.Remove(x.Key); 
+            res
+        member s.Contains(x) = 
+            s.ContainsKey(x.Key) && 
+            Unchecked.equals s.[x.Key] x.Value
+        member s.CopyTo(arr,arrIndex) = s |> Seq.iteri (fun j x -> arr.[arrIndex+j] <- x)
+        member s.IsReadOnly = false
+        member s.Count = s.Count
+
--- fsharp-3.1.1.26+dfsg2.orig/FSharp.PowerPack/HashMultiMap.fsi
+++ fsharp-3.1.1.26+dfsg2/FSharp.PowerPack/HashMultiMap.fsi
@@ -1,84 +1,84 @@
-// (c) Microsoft Corporation 2005-2009. 
-
-/// This namespace contains FSharp.PowerPack extensions for the F# collection types
-namespace Microsoft.FSharp.Collections
-
-open System
-open System.Collections.Generic
-
-
-/// Hash tables, by default based on F# structural "hash" and (=) functions. 
-/// The table may map a single key to multiple bindings.
-[<Sealed>]
-type HashMultiMap<'Key,'Value> =
-    /// Create a new empty mutable HashMultiMap with the given key hash/equality functions
-    new : comparer:IEqualityComparer<'Key> -> HashMultiMap<'Key,'Value>
-    
-    /// Create a new empty mutable HashMultiMap with an internal bucket array of the given approximate size
-    /// and with the given key hash/equality functions
-    new : size:int * comparer:IEqualityComparer<'Key> -> HashMultiMap<'Key,'Value>
-    
-    /// Build a map that contains the bindings of the given IEnumerable
-    new : entries:seq<'Key * 'Value> * comparer:IEqualityComparer<'Key> -> HashMultiMap<'Key,'Value>
-
-    /// Make a shallow copy of the collection
-    member Copy    : unit    -> HashMultiMap<'Key,'Value>
-    
-    /// Add a binding for the element to the table
-    member Add     : 'Key * 'Value -> unit
-    
-    /// Clear all elements from the collection
-    member Clear   : unit    -> unit
-    
-    /// Test if the collection contains any bindings for the given element
-    member ContainsKey: 'Key -> bool
-
-    /// Remove the latest binding (if any) for the given element from the table
-    member Remove : 'Key -> unit
-
-    /// Replace the latest binding (if any) for the given element.
-    member Replace : 'Key * 'Value -> unit
-
-    /// Lookup or set the given element in the table. Set replaces all existing bindings for a value with a single
-    /// bindings. Raise <c>KeyNotFoundException</c> if the element is not found.
-    member Item : 'Key -> 'Value with get,set
-
-    /// Lookup the given element in the table, returning the result as an Option
-    member TryFind : 'Key      -> 'Value option
-    
-    /// Find all bindings for the given element in the table, if any
-    member FindAll : 'Key      -> 'Value list
-
-    /// Apply the given function to each element in the collection threading the accumulating parameter
-    /// through the sequence of function applications
-    member Fold    : ('Key -> 'Value -> 'State -> 'State) -> 'State -> 'State
-
-    /// The total number of keys in the hash table
-    member Count   : int
-
-    ///Apply the given function to each binding in the hash table 
-    member Iterate : ('Key -> 'Value -> unit) -> unit
-
-    interface IDictionary<'Key, 'Value>         
-    interface ICollection<KeyValuePair<'Key, 'Value>> 
-    interface IEnumerable<KeyValuePair<'Key, 'Value>>         
-    interface System.Collections.IEnumerable 
-    
-    [<System.Obsolete("This member has been redesigned. Use 'new HashMultiMap<_,_>(HashIdentity.Structural) instead to create a HashMultiMap using F# generic hashing and equality", true)>]
-    new : unit -> HashMultiMap<'Key,'Value>
-
-    [<System.Obsolete("This member has been redesigned. Use 'new HashMultiMap<_,_>(size, HashIdentity.Structural) instead to create a HashMultiMap using F# generic hashing and equality", true)>]
-    new : size:int -> HashMultiMap<'Key,'Value>
-
-    [<System.Obsolete("This member has been redesigned. Use 'new HashMultiMap<_,_>(entries, HashIdentity.Structural) instead to create a HashMultiMap using F# generic hashing and equality", true)>]
-    new : entries:seq<'Key * 'Value> -> HashMultiMap<'Key,'Value>
-
-
-    [<System.Obsolete("This member has been redesigned. Use 'new HashMultiMap<_,_>(HashIdentity.Structural) instead to create a HashMultiMap using F# generic hashing and equality", true)>]
-    static member Create : unit -> HashMultiMap<'Key,'Value>
-
-    [<System.Obsolete("This member has been redesigned. Use 'new HashMultiMap<_,_>(size, HashIdentity.Structural) instead to create a HashMultiMap using F# generic hashing and equality", true)>]
-    static member Create : size:int -> HashMultiMap<'Key,'Value>
-
-    [<System.Obsolete("This member has been redesigned. Use 'new HashMultiMap<_,_>(entries, HashIdentity.Structural) instead to create a HashMultiMap using F# generic hashing and equality", true)>]
-    static member Create : entries:seq<'Key * 'Value> -> HashMultiMap<'Key,'Value>
+// (c) Microsoft Corporation 2005-2009. 
+
+/// This namespace contains FSharp.PowerPack extensions for the F# collection types
+namespace Microsoft.FSharp.Collections
+
+open System
+open System.Collections.Generic
+
+
+/// Hash tables, by default based on F# structural "hash" and (=) functions. 
+/// The table may map a single key to multiple bindings.
+[<Sealed>]
+type HashMultiMap<'Key,'Value> =
+    /// Create a new empty mutable HashMultiMap with the given key hash/equality functions
+    new : comparer:IEqualityComparer<'Key> -> HashMultiMap<'Key,'Value>
+    
+    /// Create a new empty mutable HashMultiMap with an internal bucket array of the given approximate size
+    /// and with the given key hash/equality functions
+    new : size:int * comparer:IEqualityComparer<'Key> -> HashMultiMap<'Key,'Value>
+    
+    /// Build a map that contains the bindings of the given IEnumerable
+    new : entries:seq<'Key * 'Value> * comparer:IEqualityComparer<'Key> -> HashMultiMap<'Key,'Value>
+
+    /// Make a shallow copy of the collection
+    member Copy    : unit    -> HashMultiMap<'Key,'Value>
+    
+    /// Add a binding for the element to the table
+    member Add     : 'Key * 'Value -> unit
+    
+    /// Clear all elements from the collection
+    member Clear   : unit    -> unit
+    
+    /// Test if the collection contains any bindings for the given element
+    member ContainsKey: 'Key -> bool
+
+    /// Remove the latest binding (if any) for the given element from the table
+    member Remove : 'Key -> unit
+
+    /// Replace the latest binding (if any) for the given element.
+    member Replace : 'Key * 'Value -> unit
+
+    /// Lookup or set the given element in the table. Set replaces all existing bindings for a value with a single
+    /// bindings. Raise <c>KeyNotFoundException</c> if the element is not found.
+    member Item : 'Key -> 'Value with get,set
+
+    /// Lookup the given element in the table, returning the result as an Option
+    member TryFind : 'Key      -> 'Value option
+    
+    /// Find all bindings for the given element in the table, if any
+    member FindAll : 'Key      -> 'Value list
+
+    /// Apply the given function to each element in the collection threading the accumulating parameter
+    /// through the sequence of function applications
+    member Fold    : ('Key -> 'Value -> 'State -> 'State) -> 'State -> 'State
+
+    /// The total number of keys in the hash table
+    member Count   : int
+
+    ///Apply the given function to each binding in the hash table 
+    member Iterate : ('Key -> 'Value -> unit) -> unit
+
+    interface IDictionary<'Key, 'Value>         
+    interface ICollection<KeyValuePair<'Key, 'Value>> 
+    interface IEnumerable<KeyValuePair<'Key, 'Value>>         
+    interface System.Collections.IEnumerable 
+    
+    [<System.Obsolete("This member has been redesigned. Use 'new HashMultiMap<_,_>(HashIdentity.Structural) instead to create a HashMultiMap using F# generic hashing and equality", true)>]
+    new : unit -> HashMultiMap<'Key,'Value>
+
+    [<System.Obsolete("This member has been redesigned. Use 'new HashMultiMap<_,_>(size, HashIdentity.Structural) instead to create a HashMultiMap using F# generic hashing and equality", true)>]
+    new : size:int -> HashMultiMap<'Key,'Value>
+
+    [<System.Obsolete("This member has been redesigned. Use 'new HashMultiMap<_,_>(entries, HashIdentity.Structural) instead to create a HashMultiMap using F# generic hashing and equality", true)>]
+    new : entries:seq<'Key * 'Value> -> HashMultiMap<'Key,'Value>
+
+
+    [<System.Obsolete("This member has been redesigned. Use 'new HashMultiMap<_,_>(HashIdentity.Structural) instead to create a HashMultiMap using F# generic hashing and equality", true)>]
+    static member Create : unit -> HashMultiMap<'Key,'Value>
+
+    [<System.Obsolete("This member has been redesigned. Use 'new HashMultiMap<_,_>(size, HashIdentity.Structural) instead to create a HashMultiMap using F# generic hashing and equality", true)>]
+    static member Create : size:int -> HashMultiMap<'Key,'Value>
+
+    [<System.Obsolete("This member has been redesigned. Use 'new HashMultiMap<_,_>(entries, HashIdentity.Structural) instead to create a HashMultiMap using F# generic hashing and equality", true)>]
+    static member Create : entries:seq<'Key * 'Value> -> HashMultiMap<'Key,'Value>
--- fsharp-3.1.1.26+dfsg2.orig/FSharp.PowerPack/HashSet.fs
+++ fsharp-3.1.1.26+dfsg2/FSharp.PowerPack/HashSet.fs
@@ -1,54 +1,54 @@
-// (c) Microsoft Corporation 2005-2009. 
-
-
-namespace Microsoft.FSharp.Collections
-
-open System
-open System.Collections
-open System.Collections.Generic
-
-// HashSets are currently implemented using the .NET Dictionary type. 
-[<Sealed>]
-type HashSet<'T>(t: Dictionary<'T,int>) = 
-
-    new (hasheq: IEqualityComparer<'T>) = 
-        new HashSet<_>(new Dictionary<_,_>(hasheq))
-
-    new (size:int,hasheq: IEqualityComparer<'T>) = 
-        new HashSet<_>(new Dictionary<_,_>(size,hasheq))
-
-    new (elements:seq<'T>, hasheq: IEqualityComparer<'T>) as t = 
-        new HashSet<_>(new Dictionary<_,_>(hasheq)) 
-        then 
-           for x in elements do t.Add x
-
-    new (size:int) = failwith "unreachable"; new HashSet<'T>(11)
-
-    new () = failwith "unreachable"; new HashSet<'T>(11)
-
-    new (seq:seq<'T>) = failwith "unreachable"; new HashSet<'T>(11)
-        
-    member x.Add(y)    = t.[y] <- 0
-
-    member x.Clear() = t.Clear()
-
-    member x.Copy() : HashSet<'T>  = 
-        let t2 = new Dictionary<'T,int>(t.Count,t.Comparer) in 
-        t |> Seq.iter (fun kvp -> t2.[kvp.Key] <- 0); 
-        new HashSet<'T>(t2)
-
-    member x.Fold f acc = 
-        let mutable res = acc
-        for kvp in t do
-            res <- f kvp.Key res
-        res
-
-    member x.Iterate(f) =  t |> Seq.iter (fun kvp -> f kvp.Key)
-
-    member x.Contains(y) = t.ContainsKey(y)
-    member x.Remove(y) = t.Remove(y) |> ignore
-    member x.Count = t.Count
-    interface IEnumerable<'T> with
-        member x.GetEnumerator() = t.Keys.GetEnumerator() :> IEnumerator<_>
-    interface System.Collections.IEnumerable with
-        member x.GetEnumerator() = t.Keys.GetEnumerator()  :> IEnumerator 
+// (c) Microsoft Corporation 2005-2009. 
+
+
+namespace Microsoft.FSharp.Collections
+
+open System
+open System.Collections
+open System.Collections.Generic
+
+// HashSets are currently implemented using the .NET Dictionary type. 
+[<Sealed>]
+type HashSet<'T>(t: Dictionary<'T,int>) = 
+
+    new (hasheq: IEqualityComparer<'T>) = 
+        new HashSet<_>(new Dictionary<_,_>(hasheq))
+
+    new (size:int,hasheq: IEqualityComparer<'T>) = 
+        new HashSet<_>(new Dictionary<_,_>(size,hasheq))
+
+    new (elements:seq<'T>, hasheq: IEqualityComparer<'T>) as t = 
+        new HashSet<_>(new Dictionary<_,_>(hasheq)) 
+        then 
+           for x in elements do t.Add x
+
+    new (size:int) = failwith "unreachable"; new HashSet<'T>(11)
+
+    new () = failwith "unreachable"; new HashSet<'T>(11)
+
+    new (seq:seq<'T>) = failwith "unreachable"; new HashSet<'T>(11)
+        
+    member x.Add(y)    = t.[y] <- 0
+
+    member x.Clear() = t.Clear()
+
+    member x.Copy() : HashSet<'T>  = 
+        let t2 = new Dictionary<'T,int>(t.Count,t.Comparer) in 
+        t |> Seq.iter (fun kvp -> t2.[kvp.Key] <- 0); 
+        new HashSet<'T>(t2)
+
+    member x.Fold f acc = 
+        let mutable res = acc
+        for kvp in t do
+            res <- f kvp.Key res
+        res
+
+    member x.Iterate(f) =  t |> Seq.iter (fun kvp -> f kvp.Key)
+
+    member x.Contains(y) = t.ContainsKey(y)
+    member x.Remove(y) = t.Remove(y) |> ignore
+    member x.Count = t.Count
+    interface IEnumerable<'T> with
+        member x.GetEnumerator() = t.Keys.GetEnumerator() :> IEnumerator<_>
+    interface System.Collections.IEnumerable with
+        member x.GetEnumerator() = t.Keys.GetEnumerator()  :> IEnumerator 
--- fsharp-3.1.1.26+dfsg2.orig/FSharp.PowerPack/HashSet.fsi
+++ fsharp-3.1.1.26+dfsg2/FSharp.PowerPack/HashSet.fsi
@@ -1,59 +1,59 @@
-// (c) Microsoft Corporation 2005-2009. 
-
-namespace Microsoft.FSharp.Collections
-
-open System
-open System.Collections.Generic
-
-/// Mutable hash sets based by default on F# structural "hash" and (=) functions. Implemented via a hash table and/or Dictionary.
-[<Sealed>]
-[<Obsolete("The HashSet<_> type from the F# Power Pack is now deprecated. Use the System.Collections.Generic.HashSet<_> type from System.Core.dll instead.")>]
-type HashSet<'T>  =
-
-    /// Create a new empty mutable hash set using the given key hash/equality functions 
-    new : comparer:IEqualityComparer<'T> -> HashSet<'T>
-
-    /// Create a new empty mutable hash set with an internal bucket array of the given approximate size
-    /// and with the given key hash/equality functions 
-    new : size:int * comparer:IEqualityComparer<'T> -> HashSet<'T>
-
-    /// Create a new mutable hash set with the given elements and using the given key hash/equality functions 
-    new : elements:seq<'T> * comparer:IEqualityComparer<'T>  -> HashSet<'T>
-    
-    /// Make a shallow copy of the set
-    member Copy    : unit -> HashSet<'T>
-    
-    /// Add an element to the collection
-    member Add     : 'T   -> unit
-    
-    /// Clear all elements from the set
-    member Clear   : unit -> unit
-    
-    /// Test if the set contains the given element
-    member Contains: 'T   -> bool
-    
-    /// Remove the given element from the set
-    member Remove  : 'T   -> unit
-    
-    /// Apply the given function to the set threading the accumulating parameter
-    /// through the sequence of function applications
-    member Fold    : ('T -> 'State -> 'State) -> 'State -> 'State
-
-    /// The total number of elements in the set
-    member Count   : int
-
-    /// Apply the given function to each binding in the hash table 
-    member Iterate : ('T -> unit) -> unit
-
-    interface IEnumerable<'T> 
-    interface System.Collections.IEnumerable 
-
-    [<System.Obsolete("This member has been redesigned. Use 'new HashSet<_>(HashIdentity.Structural) to create a HashSet using F# generic hashing and equality", true)>]
-    new : unit -> HashSet<'T>
-
-    [<System.Obsolete("This member has been redesigned. Use 'new HashSet<_>(size, HashIdentity.Structural) to create a HashSet using F# generic hashing and equality", true)>]
-    new : size:int -> HashSet<'T>
-
-    [<System.Obsolete("This member has been redesigned. Use 'new HashSet<_>(elements, HashIdentity.Structural) to create a HashSet using F# generic hashing and equality", true)>]
-    new : elements:seq<'T> -> HashSet<'T>
-
+// (c) Microsoft Corporation 2005-2009. 
+
+namespace Microsoft.FSharp.Collections
+
+open System
+open System.Collections.Generic
+
+/// Mutable hash sets based by default on F# structural "hash" and (=) functions. Implemented via a hash table and/or Dictionary.
+[<Sealed>]
+[<Obsolete("The HashSet<_> type from the F# Power Pack is now deprecated. Use the System.Collections.Generic.HashSet<_> type from System.Core.dll instead.")>]
+type HashSet<'T>  =
+
+    /// Create a new empty mutable hash set using the given key hash/equality functions 
+    new : comparer:IEqualityComparer<'T> -> HashSet<'T>
+
+    /// Create a new empty mutable hash set with an internal bucket array of the given approximate size
+    /// and with the given key hash/equality functions 
+    new : size:int * comparer:IEqualityComparer<'T> -> HashSet<'T>
+
+    /// Create a new mutable hash set with the given elements and using the given key hash/equality functions 
+    new : elements:seq<'T> * comparer:IEqualityComparer<'T>  -> HashSet<'T>
+    
+    /// Make a shallow copy of the set
+    member Copy    : unit -> HashSet<'T>
+    
+    /// Add an element to the collection
+    member Add     : 'T   -> unit
+    
+    /// Clear all elements from the set
+    member Clear   : unit -> unit
+    
+    /// Test if the set contains the given element
+    member Contains: 'T   -> bool
+    
+    /// Remove the given element from the set
+    member Remove  : 'T   -> unit
+    
+    /// Apply the given function to the set threading the accumulating parameter
+    /// through the sequence of function applications
+    member Fold    : ('T -> 'State -> 'State) -> 'State -> 'State
+
+    /// The total number of elements in the set
+    member Count   : int
+
+    /// Apply the given function to each binding in the hash table 
+    member Iterate : ('T -> unit) -> unit
+
+    interface IEnumerable<'T> 
+    interface System.Collections.IEnumerable 
+
+    [<System.Obsolete("This member has been redesigned. Use 'new HashSet<_>(HashIdentity.Structural) to create a HashSet using F# generic hashing and equality", true)>]
+    new : unit -> HashSet<'T>
+
+    [<System.Obsolete("This member has been redesigned. Use 'new HashSet<_>(size, HashIdentity.Structural) to create a HashSet using F# generic hashing and equality", true)>]
+    new : size:int -> HashSet<'T>
+
+    [<System.Obsolete("This member has been redesigned. Use 'new HashSet<_>(elements, HashIdentity.Structural) to create a HashSet using F# generic hashing and equality", true)>]
+    new : elements:seq<'T> -> HashSet<'T>
+
--- fsharp-3.1.1.26+dfsg2.orig/FSharp.PowerPack/Lazy.fs
+++ fsharp-3.1.1.26+dfsg2/FSharp.PowerPack/Lazy.fs
@@ -1,6 +1,6 @@
-// (c) Microsoft Corporation 2005-2009.  
-
-[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
-module Microsoft.FSharp.Core.Lazy
-
-let force (x: Lazy<'T>) = x.Force()
+// (c) Microsoft Corporation 2005-2009.  
+
+[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+module Microsoft.FSharp.Core.Lazy
+
+let force (x: Lazy<'T>) = x.Force()
--- fsharp-3.1.1.26+dfsg2.orig/FSharp.PowerPack/Lazy.fsi
+++ fsharp-3.1.1.26+dfsg2/FSharp.PowerPack/Lazy.fsi
@@ -1,7 +1,7 @@
-// (c) Microsoft Corporation 2005-2009.  
-
-[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
-module Microsoft.FSharp.Core.Lazy
-
-/// See Lazy.Force
-val force: Lazy<'T> -> 'T
+// (c) Microsoft Corporation 2005-2009.  
+
+[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+module Microsoft.FSharp.Core.Lazy
+
+/// See Lazy.Force
+val force: Lazy<'T> -> 'T
--- fsharp-3.1.1.26+dfsg2.orig/FSharp.PowerPack/LazyList.fs
+++ fsharp-3.1.1.26+dfsg2/FSharp.PowerPack/LazyList.fs
@@ -1,262 +1,262 @@
-// (c) Microsoft Corporation 2005-2009.  
-
-namespace Microsoft.FSharp.Collections
-
-open System
-open System.Collections.Generic
-
-#nowarn "21" // recursive initialization
-#nowarn "40" // recursive initialization
-
-exception UndefinedException
-
-[<NoEquality; NoComparison>]
-type LazyList<'T> =
-    { mutable status : LazyCellStatus< 'T > }
-    
-    member x.Value = 
-        match x.status with 
-        | LazyCellStatus.Value v -> v
-        | _ -> 
-            lock x (fun () -> 
-                match x.status with 
-                | LazyCellStatus.Delayed f -> 
-                    x.status <- Exception UndefinedException; 
-                    try 
-                        let res = f () 
-                        x.status <- LazyCellStatus.Value res; 
-                        res 
-                    with e -> 
-                        x.status <- LazyCellStatus.Exception(e); 
-                        reraise()
-                | LazyCellStatus.Value v -> v
-                | LazyCellStatus.Exception e -> raise e)
-    
-    member s.GetEnumeratorImpl() = 
-        let getCell (x : LazyList<'T>) = x.Value
-        let toSeq s = Seq.unfold (fun ll -> match getCell ll with CellEmpty -> None | CellCons(a,b) -> Some(a,b)) s 
-        (toSeq s).GetEnumerator()
-            
-    interface IEnumerable<'T> with
-        member s.GetEnumerator() = s.GetEnumeratorImpl()
-
-    interface System.Collections.IEnumerable with
-        override s.GetEnumerator() = (s.GetEnumeratorImpl() :> System.Collections.IEnumerator)
-
-
-and 
-    [<NoEquality; NoComparison>]
-    LazyCellStatus<'T> =
-    | Delayed of (unit -> LazyListCell<'T> )
-    | Value of LazyListCell<'T> 
-    | Exception of System.Exception
-
-
-and 
-    [<NoEquality; NoComparison>]
-    LazyListCell<'T> = 
-    | CellCons of 'T * LazyList<'T> 
-    | CellEmpty
-
-[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
-module LazyList = 
-
-    let lzy f = { status = Delayed f }
-    let force (x: LazyList<'T>) = x.Value
-
-    let notlazy v = { status = Value v }
-    
-    type EmptyValue<'T>() = 
-        static let value : LazyList<'T> = notlazy CellEmpty
-        static member Value : LazyList<'T> = value
-        
-    [<NoEquality; NoComparison>]
-    type LazyItem<'T> = Cons of 'T * LazyList<'T> | Empty
-    type 'T item = 'T LazyItem
-    let get (x : LazyList<'T>) = match force x with CellCons (a,b) -> Some(a,b) | CellEmpty -> None
-    let getCell (x : LazyList<'T>) = force x 
-    let empty<'T> : LazyList<'T> = EmptyValue<'T>.Value
-    let consc x l = CellCons(x,l)
-    let cons x l = lzy(fun () -> (consc x l))
-    let consDelayed x l = lzy(fun () -> (consc x (lzy(fun () ->  (force (l()))))))
-    let consf x l = consDelayed x l
-
-    let rec unfold f z = 
-      lzy(fun () -> 
-          match f z with
-          | None       -> CellEmpty
-          | Some (x,z) -> CellCons (x,unfold f z))
-
-    let rec append l1  l2 = lzy(fun () ->  (appendc l1 l2))
-    and appendc l1 l2 =
-      match getCell l1 with
-      | CellEmpty -> force l2
-      | CellCons(a,b) -> consc a (append b l2)
-
-    let delayed f = lzy(fun () ->  (getCell (f())))
-    let repeat x = 
-      let rec s = cons x (delayed (fun () -> s)) in s
-
-    let rec map f s = 
-      lzy(fun () ->  
-        match getCell s with
-        | CellEmpty -> CellEmpty
-        | CellCons(a,b) -> consc (f a) (map f b))
-
-    let rec map2 f s1 s2 =  
-      lzy(fun () -> 
-        match getCell s1, getCell s2  with
-        | CellCons(a1,b1),CellCons(a2,b2) -> consc (f a1 a2) (map2 f b1 b2)
-        | _ -> CellEmpty)
-
-    let rec zip s1 s2 = 
-      lzy(fun () -> 
-        match getCell s1, getCell s2  with
-        | CellCons(a1,b1),CellCons(a2,b2) -> consc (a1,a2) (zip b1 b2)
-        | _ -> CellEmpty)
-    let combine s1 s2 = zip s1 s2
-
-    let rec concat s1 = 
-      lzy(fun () -> 
-        match getCell s1 with
-        | CellCons(a,b) -> appendc a (concat b)
-        | CellEmpty -> CellEmpty)
-      
-    let rec filter p s1= lzy(fun () ->  filterc p s1)
-    and filterc p s1 =
-        match getCell s1 with
-        | CellCons(a,b) -> if p a then consc a (filter p b) else filterc p b
-        | CellEmpty -> CellEmpty
-      
-    let rec tryFind p s1 =
-        match getCell s1 with
-        | CellCons(a,b) -> if p a then Some a else tryFind p b
-        | CellEmpty -> None
-
-    let first p s1 = tryFind p s1
-
-    let indexNotFound() = raise (new System.Collections.Generic.KeyNotFoundException("An index satisfying the predicate was not found in the collection"))
-
-    let find p s1 =
-        match tryFind p s1 with
-        | Some a -> a
-        | None   -> indexNotFound()
-
-    let rec scan f acc s1 = 
-      lzy(fun () -> 
-        match getCell s1 with
-        | CellCons(a,b) -> let acc' = f acc a in consc acc (scan f acc' b)
-        | CellEmpty -> consc acc empty)
-
-    let folds f acc s1 = scan f acc s1 // deprecated
-
-    let head s = 
-      match getCell s with
-      | CellCons(a,_) -> a
-      | CellEmpty -> invalidArg "s" "the list is empty"
-
-    let tail s = 
-      match getCell s with
-      | CellCons(_,b) -> b
-      | CellEmpty -> invalidArg "s" "the list is empty"
-
-    let isEmpty s =
-      match getCell s with
-      | CellCons _ -> false
-      | CellEmpty -> true
-
-    let rec take n s = 
-      lzy(fun () -> 
-        if n < 0 then invalidArg "n" "the number must not be negative"
-        elif n = 0 then CellEmpty 
-        else
-          match getCell s with
-          | CellCons(a,s) -> consc a (take (n-1) s)
-          | CellEmpty -> invalidArg "n" "not enough items in the list" )
-
-    let rec skipc n s =
-      if n = 0 then force s 
-      else  
-        match getCell s with
-        | CellCons(_,s) -> skipc (n-1) s
-        | CellEmpty -> invalidArg "n" "not enough items in the list"
-
-    let rec skip n s = 
-      lzy(fun () -> 
-        if n < 0 then invalidArg "n" "the value must not be negative"
-        else skipc n s)
-
-    let rec ofList l = 
-      lzy(fun () -> 
-        match l with [] -> CellEmpty | h :: t -> consc h (ofList t))
-      
-    let toList s = 
-      let rec loop s acc = 
-          match getCell s with
-          | CellEmpty -> List.rev acc
-          | CellCons(h,t) -> loop t (h::acc)
-      loop s []
-      
-    let rec iter f s = 
-      match getCell s with
-      | CellEmpty -> ()
-      | CellCons(h,t) -> f h; iter f t
-      
-    let rec copyFrom i a = 
-      lzy(fun () -> 
-        if i >= Array.length a then CellEmpty 
-        else consc a.[i] (copyFrom (i+1) a))
-      
-    let rec copyTo (arr: _[]) s i = 
-      match getCell s with
-      | CellEmpty -> ()
-      | CellCons(a,b) -> arr.[i] <- a; copyTo arr b (i+1)
-
-    let ofArray a = copyFrom 0 a
-    let toArray s = Array.ofList (toList s)
-      
-    let rec lengthAux n s = 
-      match getCell s with
-      | CellEmpty -> n
-      | CellCons(_,b) -> lengthAux (n+1) b
-
-    let length s = lengthAux 0 s
-
-    let toSeq (s: LazyList<'T>) = (s :> IEnumerable<_>)
-
-    // Note: this doesn't dispose of the IEnumerator if the iteration is not run to the end
-    let rec ofFreshIEnumerator (e : IEnumerator<_>) = 
-      lzy(fun () -> 
-        if e.MoveNext() then 
-          consc e.Current (ofFreshIEnumerator e)
-        else 
-           e.Dispose()
-           CellEmpty)
-      
-    let ofSeq (c : IEnumerable<_>) =
-      ofFreshIEnumerator (c.GetEnumerator()) 
-      
-    let (|Cons|Nil|) l = match getCell l with CellCons(a,b) -> Cons(a,b) | CellEmpty -> Nil
-
-
-    let hd s = head s
-
-    let tl s = tail s
-
-    let drop n s = skip n s
-
-    let nonempty s = not (isEmpty s)
-
-    let of_list l = ofList l
-
-    let of_seq l = ofSeq l
-
-    let of_array l = ofArray l
-
-    let to_seq l = toSeq l
-
-    let to_list l = toList l
-
-    let to_array l = toArray l
-
-
+// (c) Microsoft Corporation 2005-2009.  
+
+namespace Microsoft.FSharp.Collections
+
+open System
+open System.Collections.Generic
+
+#nowarn "21" // recursive initialization
+#nowarn "40" // recursive initialization
+
+exception UndefinedException
+
+[<NoEquality; NoComparison>]
+type LazyList<'T> =
+    { mutable status : LazyCellStatus< 'T > }
+    
+    member x.Value = 
+        match x.status with 
+        | LazyCellStatus.Value v -> v
+        | _ -> 
+            lock x (fun () -> 
+                match x.status with 
+                | LazyCellStatus.Delayed f -> 
+                    x.status <- Exception UndefinedException; 
+                    try 
+                        let res = f () 
+                        x.status <- LazyCellStatus.Value res; 
+                        res 
+                    with e -> 
+                        x.status <- LazyCellStatus.Exception(e); 
+                        reraise()
+                | LazyCellStatus.Value v -> v
+                | LazyCellStatus.Exception e -> raise e)
+    
+    member s.GetEnumeratorImpl() = 
+        let getCell (x : LazyList<'T>) = x.Value
+        let toSeq s = Seq.unfold (fun ll -> match getCell ll with CellEmpty -> None | CellCons(a,b) -> Some(a,b)) s 
+        (toSeq s).GetEnumerator()
+            
+    interface IEnumerable<'T> with
+        member s.GetEnumerator() = s.GetEnumeratorImpl()
+
+    interface System.Collections.IEnumerable with
+        override s.GetEnumerator() = (s.GetEnumeratorImpl() :> System.Collections.IEnumerator)
+
+
+and 
+    [<NoEquality; NoComparison>]
+    LazyCellStatus<'T> =
+    | Delayed of (unit -> LazyListCell<'T> )
+    | Value of LazyListCell<'T> 
+    | Exception of System.Exception
+
+
+and 
+    [<NoEquality; NoComparison>]
+    LazyListCell<'T> = 
+    | CellCons of 'T * LazyList<'T> 
+    | CellEmpty
+
+[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+module LazyList = 
+
+    let lzy f = { status = Delayed f }
+    let force (x: LazyList<'T>) = x.Value
+
+    let notlazy v = { status = Value v }
+    
+    type EmptyValue<'T>() = 
+        static let value : LazyList<'T> = notlazy CellEmpty
+        static member Value : LazyList<'T> = value
+        
+    [<NoEquality; NoComparison>]
+    type LazyItem<'T> = Cons of 'T * LazyList<'T> | Empty
+    type 'T item = 'T LazyItem
+    let get (x : LazyList<'T>) = match force x with CellCons (a,b) -> Some(a,b) | CellEmpty -> None
+    let getCell (x : LazyList<'T>) = force x 
+    let empty<'T> : LazyList<'T> = EmptyValue<'T>.Value
+    let consc x l = CellCons(x,l)
+    let cons x l = lzy(fun () -> (consc x l))
+    let consDelayed x l = lzy(fun () -> (consc x (lzy(fun () ->  (force (l()))))))
+    let consf x l = consDelayed x l
+
+    let rec unfold f z = 
+      lzy(fun () -> 
+          match f z with
+          | None       -> CellEmpty
+          | Some (x,z) -> CellCons (x,unfold f z))
+
+    let rec append l1  l2 = lzy(fun () ->  (appendc l1 l2))
+    and appendc l1 l2 =
+      match getCell l1 with
+      | CellEmpty -> force l2
+      | CellCons(a,b) -> consc a (append b l2)
+
+    let delayed f = lzy(fun () ->  (getCell (f())))
+    let repeat x = 
+      let rec s = cons x (delayed (fun () -> s)) in s
+
+    let rec map f s = 
+      lzy(fun () ->  
+        match getCell s with
+        | CellEmpty -> CellEmpty
+        | CellCons(a,b) -> consc (f a) (map f b))
+
+    let rec map2 f s1 s2 =  
+      lzy(fun () -> 
+        match getCell s1, getCell s2  with
+        | CellCons(a1,b1),CellCons(a2,b2) -> consc (f a1 a2) (map2 f b1 b2)
+        | _ -> CellEmpty)
+
+    let rec zip s1 s2 = 
+      lzy(fun () -> 
+        match getCell s1, getCell s2  with
+        | CellCons(a1,b1),CellCons(a2,b2) -> consc (a1,a2) (zip b1 b2)
+        | _ -> CellEmpty)
+    let combine s1 s2 = zip s1 s2
+
+    let rec concat s1 = 
+      lzy(fun () -> 
+        match getCell s1 with
+        | CellCons(a,b) -> appendc a (concat b)
+        | CellEmpty -> CellEmpty)
+      
+    let rec filter p s1= lzy(fun () ->  filterc p s1)
+    and filterc p s1 =
+        match getCell s1 with
+        | CellCons(a,b) -> if p a then consc a (filter p b) else filterc p b
+        | CellEmpty -> CellEmpty
+      
+    let rec tryFind p s1 =
+        match getCell s1 with
+        | CellCons(a,b) -> if p a then Some a else tryFind p b
+        | CellEmpty -> None
+
+    let first p s1 = tryFind p s1
+
+    let indexNotFound() = raise (new System.Collections.Generic.KeyNotFoundException("An index satisfying the predicate was not found in the collection"))
+
+    let find p s1 =
+        match tryFind p s1 with
+        | Some a -> a
+        | None   -> indexNotFound()
+
+    let rec scan f acc s1 = 
+      lzy(fun () -> 
+        match getCell s1 with
+        | CellCons(a,b) -> let acc' = f acc a in consc acc (scan f acc' b)
+        | CellEmpty -> consc acc empty)
+
+    let folds f acc s1 = scan f acc s1 // deprecated
+
+    let head s = 
+      match getCell s with
+      | CellCons(a,_) -> a
+      | CellEmpty -> invalidArg "s" "the list is empty"
+
+    let tail s = 
+      match getCell s with
+      | CellCons(_,b) -> b
+      | CellEmpty -> invalidArg "s" "the list is empty"
+
+    let isEmpty s =
+      match getCell s with
+      | CellCons _ -> false
+      | CellEmpty -> true
+
+    let rec take n s = 
+      lzy(fun () -> 
+        if n < 0 then invalidArg "n" "the number must not be negative"
+        elif n = 0 then CellEmpty 
+        else
+          match getCell s with
+          | CellCons(a,s) -> consc a (take (n-1) s)
+          | CellEmpty -> invalidArg "n" "not enough items in the list" )
+
+    let rec skipc n s =
+      if n = 0 then force s 
+      else  
+        match getCell s with
+        | CellCons(_,s) -> skipc (n-1) s
+        | CellEmpty -> invalidArg "n" "not enough items in the list"
+
+    let rec skip n s = 
+      lzy(fun () -> 
+        if n < 0 then invalidArg "n" "the value must not be negative"
+        else skipc n s)
+
+    let rec ofList l = 
+      lzy(fun () -> 
+        match l with [] -> CellEmpty | h :: t -> consc h (ofList t))
+      
+    let toList s = 
+      let rec loop s acc = 
+          match getCell s with
+          | CellEmpty -> List.rev acc
+          | CellCons(h,t) -> loop t (h::acc)
+      loop s []
+      
+    let rec iter f s = 
+      match getCell s with
+      | CellEmpty -> ()
+      | CellCons(h,t) -> f h; iter f t
+      
+    let rec copyFrom i a = 
+      lzy(fun () -> 
+        if i >= Array.length a then CellEmpty 
+        else consc a.[i] (copyFrom (i+1) a))
+      
+    let rec copyTo (arr: _[]) s i = 
+      match getCell s with
+      | CellEmpty -> ()
+      | CellCons(a,b) -> arr.[i] <- a; copyTo arr b (i+1)
+
+    let ofArray a = copyFrom 0 a
+    let toArray s = Array.ofList (toList s)
+      
+    let rec lengthAux n s = 
+      match getCell s with
+      | CellEmpty -> n
+      | CellCons(_,b) -> lengthAux (n+1) b
+
+    let length s = lengthAux 0 s
+
+    let toSeq (s: LazyList<'T>) = (s :> IEnumerable<_>)
+
+    // Note: this doesn't dispose of the IEnumerator if the iteration is not run to the end
+    let rec ofFreshIEnumerator (e : IEnumerator<_>) = 
+      lzy(fun () -> 
+        if e.MoveNext() then 
+          consc e.Current (ofFreshIEnumerator e)
+        else 
+           e.Dispose()
+           CellEmpty)
+      
+    let ofSeq (c : IEnumerable<_>) =
+      ofFreshIEnumerator (c.GetEnumerator()) 
+      
+    let (|Cons|Nil|) l = match getCell l with CellCons(a,b) -> Cons(a,b) | CellEmpty -> Nil
+
+
+    let hd s = head s
+
+    let tl s = tail s
+
+    let drop n s = skip n s
+
+    let nonempty s = not (isEmpty s)
+
+    let of_list l = ofList l
+
+    let of_seq l = ofSeq l
+
+    let of_array l = ofArray l
+
+    let to_seq l = toSeq l
+
+    let to_list l = toList l
+
+    let to_array l = toArray l
+
+
--- fsharp-3.1.1.26+dfsg2.orig/FSharp.PowerPack/LazyList.fsi
+++ fsharp-3.1.1.26+dfsg2/FSharp.PowerPack/LazyList.fsi
@@ -1,189 +1,189 @@
-// (c) Microsoft Corporation 2005-2009. 
-
-namespace Microsoft.FSharp.Collections
-
-open System.Collections.Generic
-
-/// LazyLists are possibly-infinite, cached sequences.  See also IEnumerable/Seq for
-/// uncached sequences. LazyLists normally involve delayed computations without 
-/// side-effects.  The results of these computations are cached and evaluations will be 
-/// performed only once for each element of the lazy list.  In contrast, for sequences 
-/// (IEnumerable) recomputation happens each time an enumerator is created and the sequence 
-/// traversed.
-///
-/// LazyLists can represent cached, potentially-infinite computations.  Because they are 
-/// cached they may cause memory leaks if some active code or data structure maintains a 
-/// live reference to the head of an infinite or very large lazy list while iterating it, 
-/// or if a reference is maintained after the list is no longer required.
-///
-/// Lazy lists may be matched using the LazyList.Cons and LazyList.Nil active patterns. 
-/// These may force the computation of elements of the list.
-
-[<Sealed>]
-type LazyList<'T> =
-    interface IEnumerable<'T>
-    interface System.Collections.IEnumerable
-    
-
-[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
-module LazyList =
-
-    /// Test if a list is empty.  Forces the evaluation of
-    /// the first element of the stream if it is not already evaluated.
-    val isEmpty: LazyList<'T> -> bool
-
-    /// Return the first element of the list.  Forces the evaluation of
-    /// the first cell of the list if it is not already evaluated.
-    val head       : LazyList<'T> -> 'T
-
-    /// Return the list corresponding to the remaining items in the sequence.  
-    /// Forces the evaluation of the first cell of the list if it is not already evaluated.
-    val tail       : LazyList<'T> -> LazyList<'T>
-
-    /// Get the first cell of the list.
-    val get      : LazyList<'T> -> ('T * LazyList<'T>) option  
-
-    /// Return the list which on consumption will consist of at most 'n' elements of 
-    /// the input list.  
-    val take     : count:int -> source:LazyList<'T> -> LazyList<'T>
-
-    /// Return the list which on consumption will skip the first 'n' elements of 
-    /// the input list.  
-    val skip     : count:int -> source:LazyList<'T> -> LazyList<'T>
-
-    /// Apply the given function to successive elements of the list, returning the first
-    /// result where function returns <c>Some(x)</c> for some x. If the function never returns
-    /// true, 'None' is returned.
-    val tryFind    : predicate:('T -> bool) -> source:LazyList<'T> -> 'T option
-
-    /// Return the first element for which the given function returns <c>true</c>.
-    /// Raise <c>KeyNotFoundException</c> if no such element exists.
-    val find     : predicate:('T -> bool) -> source:LazyList<'T> -> 'T 
-
-    /// Evaluates to the list that contains no items
-    [<GeneralizableValue>]
-    val empty<'T>    : LazyList<'T>
-
-    /// Return the length of the list
-    val length: list:LazyList<'T> -> int
-
-    /// Return a new list which contains the given item followed by the
-    /// given list.
-    val cons     : 'T -> LazyList<'T>               -> LazyList<'T>
-
-    /// Return a new list which on consumption contains the given item 
-    /// followed by the list returned by the given computation.  The 
-    val consDelayed    : 'T -> (unit -> LazyList<'T>)     -> LazyList<'T>
-
-    /// Return the list which on consumption will consist of an infinite sequence of 
-    /// the given item
-    val repeat   : 'T -> LazyList<'T>
-
-    /// Return a list that is in effect the list returned by the given computation.
-    /// The given computation is not executed until the first element on the list is
-    /// consumed.
-    val delayed  : (unit -> LazyList<'T>)           -> LazyList<'T>
-
-    /// Return a list that contains the elements returned by the given computation.
-    /// The given computation is not executed until the first element on the list is
-    /// consumed.  The given argument is passed to the computation.  Subsequent elements
-    /// in the list are generated by again applying the residual 'b to the computation.
-    val unfold   : ('State -> ('T * 'State) option) -> 'State -> LazyList<'T>
-
-    /// Return the list which contains on demand the elements of the first list followed
-    /// by the elements of the second list
-    val append   : LazyList<'T> -> source:LazyList<'T> -> LazyList<'T>
-
-    /// Return the list which contains on demand the pair of elements of the first and second list
-    val zip  : LazyList<'T1> -> LazyList<'T2> -> LazyList<'T1 * 'T2>
-
-    /// Return the list which contains on demand the list of elements of the list of lazy lists.
-    val concat   : LazyList< LazyList<'T>> -> LazyList<'T>
-
-    /// Return a new collection which on consumption will consist of only the elements of the collection
-    /// for which the given predicate returns "true"
-    val filter   : predicate:('T -> bool) -> source:LazyList<'T> -> LazyList<'T>
-
-    /// Apply the given function to each element of the collection. 
-    val iter: action:('T -> unit) -> list:LazyList<'T>-> unit
-
-    /// Return a new list consisting of the results of applying the given accumulating function
-    /// to successive elements of the list
-    val scan    : folder:('State -> 'T -> 'State) -> 'State -> source:LazyList<'T> -> LazyList<'State>  
-
-    /// Build a new collection whose elements are the results of applying the given function
-    /// to each of the elements of the collection.
-    val map      : mapping:('T -> 'U) -> source:LazyList<'T> -> LazyList<'U>
-
-    /// Build a new collection whose elements are the results of applying the given function
-    /// to the corresponding elements of the two collections pairwise.
-    val map2     : mapping:('T1 -> 'T2 -> 'U) -> LazyList<'T1> -> LazyList<'T2> -> LazyList<'U>
-
-    /// Build a collection from the given array. This function will eagerly evaluate all of the 
-    /// list (and thus may not terminate). 
-    val ofArray : 'T array -> LazyList<'T>
-
-    /// Build an array from the given collection
-    val toArray : LazyList<'T> -> 'T array
-
-    /// Build a collection from the given list. This function will eagerly evaluate all of the 
-    /// list (and thus may not terminate). 
-    val ofList  : list<'T> -> LazyList<'T>
-
-    /// Build a non-lazy list from the given collection. This function will eagerly evaluate all of the 
-    /// list (and thus may not terminate). 
-    val toList  : LazyList<'T> -> list<'T>
-
-    /// Return a view of the collection as an enumerable object
-    val toSeq: LazyList<'T> -> seq<'T>
-
-    /// Build a new collection from the given enumerable object
-    val ofSeq: seq<'T> -> LazyList<'T>
-
-    [<System.Obsolete("This function has been renamed. Use 'LazyList.consDelayed' instead")>]
-    val consf    : 'T -> (unit -> LazyList<'T>)     -> LazyList<'T>
-
-    [<System.Obsolete("This function has been renamed. Use 'LazyList.head' instead")>]
-    val hd: LazyList<'T> -> 'T
-
-    [<System.Obsolete("This function has been renamed. Use 'LazyList.tail' instead")>]
-    val tl     : LazyList<'T> -> LazyList<'T>
-
-    [<System.Obsolete("This function will be removed. Use 'not (LazyList.isEmpty list)' instead")>]
-    val nonempty : LazyList<'T> -> bool
-
-    [<System.Obsolete("This function has been renamed. Use 'LazyList.skip' instead")>]
-    val drop     : count:int -> source:LazyList<'T> -> LazyList<'T>
-
-    [<System.Obsolete("This function has been renamed to 'tryFind'")>]
-    val first    : predicate:('T -> bool) -> source:LazyList<'T> -> 'T option
-
-    [<System.Obsolete("This function has been renamed. Use 'LazyList.ofArray' instead")>]
-    val of_array : 'T array -> LazyList<'T>
-
-    [<System.Obsolete("This function has been renamed. Use 'LazyList.toArray' instead")>]
-    val to_array : LazyList<'T> -> 'T array
-
-    [<System.Obsolete("This function has been renamed. Use 'LazyList.ofList' instead")>]
-    val of_list  : list<'T> -> LazyList<'T>
-
-    [<System.Obsolete("This function has been renamed. Use 'LazyList.toList' instead")>]
-    val to_list  : LazyList<'T> -> list<'T>
-
-    [<System.Obsolete("This function has been renamed. Use 'LazyList.toSeq' instead")>]
-    val to_seq: LazyList<'T> -> seq<'T>
-
-    [<System.Obsolete("This function has been renamed. Use 'LazyList.ofSeq' instead")>]
-    val of_seq: seq<'T> -> LazyList<'T>
-
-    [<System.Obsolete("This function has been renamed to 'scan'")>]
-    val folds    : folder:('State -> 'T -> 'State) -> 'State -> source:LazyList<'T> -> LazyList<'State>  
-
-    [<System.Obsolete("This function has been renamed to 'zip'")>]
-    val combine  : LazyList<'T1> -> LazyList<'T2> -> LazyList<'T1 * 'T2>
-
-    //--------------------------------------------------------------------------
-    // Lazy list active patterns
-
-    val (|Cons|Nil|) : LazyList<'T> -> Choice<('T * LazyList<'T>),unit>
-
+// (c) Microsoft Corporation 2005-2009. 
+
+namespace Microsoft.FSharp.Collections
+
+open System.Collections.Generic
+
+/// LazyLists are possibly-infinite, cached sequences.  See also IEnumerable/Seq for
+/// uncached sequences. LazyLists normally involve delayed computations without 
+/// side-effects.  The results of these computations are cached and evaluations will be 
+/// performed only once for each element of the lazy list.  In contrast, for sequences 
+/// (IEnumerable) recomputation happens each time an enumerator is created and the sequence 
+/// traversed.
+///
+/// LazyLists can represent cached, potentially-infinite computations.  Because they are 
+/// cached they may cause memory leaks if some active code or data structure maintains a 
+/// live reference to the head of an infinite or very large lazy list while iterating it, 
+/// or if a reference is maintained after the list is no longer required.
+///
+/// Lazy lists may be matched using the LazyList.Cons and LazyList.Nil active patterns. 
+/// These may force the computation of elements of the list.
+
+[<Sealed>]
+type LazyList<'T> =
+    interface IEnumerable<'T>
+    interface System.Collections.IEnumerable
+    
+
+[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+module LazyList =
+
+    /// Test if a list is empty.  Forces the evaluation of
+    /// the first element of the stream if it is not already evaluated.
+    val isEmpty: LazyList<'T> -> bool
+
+    /// Return the first element of the list.  Forces the evaluation of
+    /// the first cell of the list if it is not already evaluated.
+    val head       : LazyList<'T> -> 'T
+
+    /// Return the list corresponding to the remaining items in the sequence.  
+    /// Forces the evaluation of the first cell of the list if it is not already evaluated.
+    val tail       : LazyList<'T> -> LazyList<'T>
+
+    /// Get the first cell of the list.
+    val get      : LazyList<'T> -> ('T * LazyList<'T>) option  
+
+    /// Return the list which on consumption will consist of at most 'n' elements of 
+    /// the input list.  
+    val take     : count:int -> source:LazyList<'T> -> LazyList<'T>
+
+    /// Return the list which on consumption will skip the first 'n' elements of 
+    /// the input list.  
+    val skip     : count:int -> source:LazyList<'T> -> LazyList<'T>
+
+    /// Apply the given function to successive elements of the list, returning the first
+    /// result where function returns <c>Some(x)</c> for some x. If the function never returns
+    /// true, 'None' is returned.
+    val tryFind    : predicate:('T -> bool) -> source:LazyList<'T> -> 'T option
+
+    /// Return the first element for which the given function returns <c>true</c>.
+    /// Raise <c>KeyNotFoundException</c> if no such element exists.
+    val find     : predicate:('T -> bool) -> source:LazyList<'T> -> 'T 
+
+    /// Evaluates to the list that contains no items
+    [<GeneralizableValue>]
+    val empty<'T>    : LazyList<'T>
+
+    /// Return the length of the list
+    val length: list:LazyList<'T> -> int
+
+    /// Return a new list which contains the given item followed by the
+    /// given list.
+    val cons     : 'T -> LazyList<'T>               -> LazyList<'T>
+
+    /// Return a new list which on consumption contains the given item 
+    /// followed by the list returned by the given computation.  The 
+    val consDelayed    : 'T -> (unit -> LazyList<'T>)     -> LazyList<'T>
+
+    /// Return the list which on consumption will consist of an infinite sequence of 
+    /// the given item
+    val repeat   : 'T -> LazyList<'T>
+
+    /// Return a list that is in effect the list returned by the given computation.
+    /// The given computation is not executed until the first element on the list is
+    /// consumed.
+    val delayed  : (unit -> LazyList<'T>)           -> LazyList<'T>
+
+    /// Return a list that contains the elements returned by the given computation.
+    /// The given computation is not executed until the first element on the list is
+    /// consumed.  The given argument is passed to the computation.  Subsequent elements
+    /// in the list are generated by again applying the residual 'b to the computation.
+    val unfold   : ('State -> ('T * 'State) option) -> 'State -> LazyList<'T>
+
+    /// Return the list which contains on demand the elements of the first list followed
+    /// by the elements of the second list
+    val append   : LazyList<'T> -> source:LazyList<'T> -> LazyList<'T>
+
+    /// Return the list which contains on demand the pair of elements of the first and second list
+    val zip  : LazyList<'T1> -> LazyList<'T2> -> LazyList<'T1 * 'T2>
+
+    /// Return the list which contains on demand the list of elements of the list of lazy lists.
+    val concat   : LazyList< LazyList<'T>> -> LazyList<'T>
+
+    /// Return a new collection which on consumption will consist of only the elements of the collection
+    /// for which the given predicate returns "true"
+    val filter   : predicate:('T -> bool) -> source:LazyList<'T> -> LazyList<'T>
+
+    /// Apply the given function to each element of the collection. 
+    val iter: action:('T -> unit) -> list:LazyList<'T>-> unit
+
+    /// Return a new list consisting of the results of applying the given accumulating function
+    /// to successive elements of the list
+    val scan    : folder:('State -> 'T -> 'State) -> 'State -> source:LazyList<'T> -> LazyList<'State>  
+
+    /// Build a new collection whose elements are the results of applying the given function
+    /// to each of the elements of the collection.
+    val map      : mapping:('T -> 'U) -> source:LazyList<'T> -> LazyList<'U>
+
+    /// Build a new collection whose elements are the results of applying the given function
+    /// to the corresponding elements of the two collections pairwise.
+    val map2     : mapping:('T1 -> 'T2 -> 'U) -> LazyList<'T1> -> LazyList<'T2> -> LazyList<'U>
+
+    /// Build a collection from the given array. This function will eagerly evaluate all of the 
+    /// list (and thus may not terminate). 
+    val ofArray : 'T array -> LazyList<'T>
+
+    /// Build an array from the given collection
+    val toArray : LazyList<'T> -> 'T array
+
+    /// Build a collection from the given list. This function will eagerly evaluate all of the 
+    /// list (and thus may not terminate). 
+    val ofList  : list<'T> -> LazyList<'T>
+
+    /// Build a non-lazy list from the given collection. This function will eagerly evaluate all of the 
+    /// list (and thus may not terminate). 
+    val toList  : LazyList<'T> -> list<'T>
+
+    /// Return a view of the collection as an enumerable object
+    val toSeq: LazyList<'T> -> seq<'T>
+
+    /// Build a new collection from the given enumerable object
+    val ofSeq: seq<'T> -> LazyList<'T>
+
+    [<System.Obsolete("This function has been renamed. Use 'LazyList.consDelayed' instead")>]
+    val consf    : 'T -> (unit -> LazyList<'T>)     -> LazyList<'T>
+
+    [<System.Obsolete("This function has been renamed. Use 'LazyList.head' instead")>]
+    val hd: LazyList<'T> -> 'T
+
+    [<System.Obsolete("This function has been renamed. Use 'LazyList.tail' instead")>]
+    val tl     : LazyList<'T> -> LazyList<'T>
+
+    [<System.Obsolete("This function will be removed. Use 'not (LazyList.isEmpty list)' instead")>]
+    val nonempty : LazyList<'T> -> bool
+
+    [<System.Obsolete("This function has been renamed. Use 'LazyList.skip' instead")>]
+    val drop     : count:int -> source:LazyList<'T> -> LazyList<'T>
+
+    [<System.Obsolete("This function has been renamed to 'tryFind'")>]
+    val first    : predicate:('T -> bool) -> source:LazyList<'T> -> 'T option
+
+    [<System.Obsolete("This function has been renamed. Use 'LazyList.ofArray' instead")>]
+    val of_array : 'T array -> LazyList<'T>
+
+    [<System.Obsolete("This function has been renamed. Use 'LazyList.toArray' instead")>]
+    val to_array : LazyList<'T> -> 'T array
+
+    [<System.Obsolete("This function has been renamed. Use 'LazyList.ofList' instead")>]
+    val of_list  : list<'T> -> LazyList<'T>
+
+    [<System.Obsolete("This function has been renamed. Use 'LazyList.toList' instead")>]
+    val to_list  : LazyList<'T> -> list<'T>
+
+    [<System.Obsolete("This function has been renamed. Use 'LazyList.toSeq' instead")>]
+    val to_seq: LazyList<'T> -> seq<'T>
+
+    [<System.Obsolete("This function has been renamed. Use 'LazyList.ofSeq' instead")>]
+    val of_seq: seq<'T> -> LazyList<'T>
+
+    [<System.Obsolete("This function has been renamed to 'scan'")>]
+    val folds    : folder:('State -> 'T -> 'State) -> 'State -> source:LazyList<'T> -> LazyList<'State>  
+
+    [<System.Obsolete("This function has been renamed to 'zip'")>]
+    val combine  : LazyList<'T1> -> LazyList<'T2> -> LazyList<'T1 * 'T2>
+
+    //--------------------------------------------------------------------------
+    // Lazy list active patterns
+
+    val (|Cons|Nil|) : LazyList<'T> -> Choice<('T * LazyList<'T>),unit>
+
--- fsharp-3.1.1.26+dfsg2.orig/FSharp.PowerPack/Lexing.fs
+++ fsharp-3.1.1.26+dfsg2/FSharp.PowerPack/Lexing.fs
@@ -1,423 +1,423 @@
-// (c) Microsoft Corporation 2005-2009.
-
-#nowarn "47" // recursive initialization of LexBuffer
-
-
-#if INTERNALIZED_POWER_PACK
-namespace Internal.Utilities.Text.Lexing
-
-#else
-namespace Microsoft.FSharp.Text.Lexing 
-#endif
-
-    open System.Collections.Generic
-
-    // REVIEW: This type showed up on a parsing-intensive performance measurement. Consider whether it can be a struct-record later when we have this feature. -jomo
-#if INTERNALIZED_POWER_PACK
-    type internal Position = 
-#else
-    type Position = 
-#endif
-        { pos_fname : string;
-          pos_lnum : int;
-#if INTERNALIZED_POWER_PACK
-          pos_orig_lnum : int;
-#endif
-          pos_bol : int;
-          pos_cnum : int; }
-        member x.FileName = x.pos_fname
-        member x.Line = x.pos_lnum
-#if INTERNALIZED_POWER_PACK
-        member x.OriginalLine = x.pos_orig_lnum
-#endif
-        member x.Char = x.pos_cnum
-        member x.AbsoluteOffset = x.pos_cnum
-        member x.StartOfLine = x.pos_bol
-        member x.StartOfLineAbsoluteOffset = x.pos_bol
-        member x.Column = x.pos_cnum - x.pos_bol
-        member pos.NextLine = 
-            { pos with 
-#if INTERNALIZED_POWER_PACK
-                    pos_orig_lnum = pos.OriginalLine + 1;
-#endif
-                    pos_lnum = pos.Line+1; 
-                    pos_bol = pos.AbsoluteOffset }
-        member pos.EndOfToken(n) = {pos with pos_cnum=pos.pos_cnum + n }
-        member pos.AsNewLinePos() = pos.NextLine
-        member pos.ShiftColumnBy(by) = {pos with pos_cnum = pos.pos_cnum + by}
-        static member Empty = 
-            { pos_fname=""; 
-              pos_lnum= 0; 
-#if INTERNALIZED_POWER_PACK
-              pos_orig_lnum = 0;
-#endif
-              pos_bol= 0; 
-              pos_cnum=0 }
-        static member FirstLine(filename) = 
-            { pos_fname=filename; 
-#if INTERNALIZED_POWER_PACK
-              pos_orig_lnum = 1;
-#endif
-              pos_lnum= 1; 
-              pos_bol= 0; 
-              pos_cnum=0 }
-
-#if INTERNALIZED_POWER_PACK
-    type internal LexBufferFiller<'char> = 
-#else
-    type LexBufferFiller<'char> = 
-#endif
-        { fillSync : (LexBuffer<'char> -> unit) option
-          fillAsync : (LexBuffer<'char> -> Async<unit>) option } 
-        
-    and [<Sealed>]
-#if INTERNALIZED_POWER_PACK
-        internal LexBuffer<'char>(filler: LexBufferFiller<'char>) as this = 
-#else
-        LexBuffer<'char>(filler: LexBufferFiller<'char>) as this = 
-#endif
-        let context = new Dictionary<string,obj>(1) in 
-        let extendBufferSync = (fun () -> match filler.fillSync with Some refill -> refill this | None -> invalidOp "attempt to read synchronously from an asynchronous lex buffer")
-        let extendBufferAsync = (fun () -> match filler.fillAsync with Some refill -> refill this | None -> invalidOp "attempt to read asynchronously from a synchronous lex buffer")
-        let mutable buffer=[||];
-        /// number of valid charactes beyond bufferScanStart 
-        let mutable bufferMaxScanLength=0;
-        /// count into the buffer when scanning 
-        let mutable bufferScanStart=0;
-        /// number of characters scanned so far 
-        let mutable bufferScanLength=0;
-        /// length of the scan at the last accepting state 
-        let mutable lexemeLength=0;
-        /// action related to the last accepting state 
-        let mutable bufferAcceptAction=0;
-        let mutable eof = false;
-        let mutable startPos = Position.Empty ;
-        let mutable endPos = Position.Empty
-
-        // Throw away all the input besides the lexeme 
-              
-        let discardInput () = 
-            let keep = Array.sub buffer bufferScanStart bufferScanLength
-            let nkeep = keep.Length 
-            Array.blit keep 0 buffer 0 nkeep;
-            bufferScanStart <- 0;
-            bufferMaxScanLength <- nkeep
-                 
-              
-        member lexbuf.EndOfScan () : int =
-            // Printf.eprintf "endOfScan, lexBuffer.lexemeLength = %d\n" lexBuffer.lexemeLength;
-            if bufferAcceptAction < 0 then 
-                failwith "unrecognized input"
-
-            //  Printf.printf "endOfScan %d state %d on unconsumed input '%c' (%d)\n" a s (Char.chr inp) inp;
-            //   Printf.eprintf "accept, lexeme = %s\n" (lexeme lexBuffer); 
-            lexbuf.StartPos <- endPos;
-            lexbuf.EndPos <- endPos.EndOfToken(lexbuf.LexemeLength);
-            bufferAcceptAction
-
-        member lexbuf.StartPos
-           with get() = startPos
-           and  set(b) =  startPos <- b
-           
-        member lexbuf.EndPos 
-           with get() = endPos
-           and  set(b) =  endPos <- b
-
-        member lexbuf.Lexeme         = Array.sub buffer bufferScanStart lexemeLength
-        member lexbuf.LexemeChar(n)  = buffer.[n+bufferScanStart]
-        
-        member lexbuf.BufferLocalStore = (context :> IDictionary<_,_>)
-        member lexbuf.LexemeLength        with get() : int = lexemeLength    and set v = lexemeLength <- v
-        member internal lexbuf.Buffer              with get() : 'char[] = buffer              and set v = buffer <- v
-        member internal lexbuf.BufferMaxScanLength with get() = bufferMaxScanLength and set v = bufferMaxScanLength <- v
-        member internal lexbuf.BufferScanLength    with get() = bufferScanLength    and set v = bufferScanLength <- v
-        member internal lexbuf.BufferScanStart     with get() : int = bufferScanStart     and set v = bufferScanStart <- v
-        member internal lexbuf.BufferAcceptAction  with get() = bufferAcceptAction  and set v = bufferAcceptAction <- v
-        member internal lexbuf.RefillBuffer = extendBufferSync
-        member internal lexbuf.AsyncRefillBuffer = extendBufferAsync
-
-        static member LexemeString(lexbuf:LexBuffer<char>) = 
-            new System.String(lexbuf.Buffer,lexbuf.BufferScanStart,lexbuf.LexemeLength)
-
-        member lexbuf.IsPastEndOfStream 
-           with get() = eof
-           and  set(b) =  eof <- b
-
-        member lexbuf.DiscardInput() = discardInput ()
-
-        member x.BufferScanPos = bufferScanStart + bufferScanLength
-
-        member lexbuf.EnsureBufferSize n = 
-            if lexbuf.BufferScanPos + n >= buffer.Length then 
-                let repl = Array.zeroCreate (lexbuf.BufferScanPos + n) 
-                Array.blit buffer bufferScanStart repl bufferScanStart bufferScanLength;
-                buffer <- repl
-
-        static member FromReadFunctions (syncRead : ('char[] * int * int -> int) option, asyncRead : ('char[] * int * int -> Async<int>) option) : LexBuffer<'char> = 
-            let extension= Array.zeroCreate 4096
-            let fillers = 
-                { fillSync = 
-                    match syncRead with 
-                    | None -> None
-                    | Some read -> 
-                         Some (fun lexBuffer -> 
-                             let n = read(extension,0,extension.Length)
-                             lexBuffer.EnsureBufferSize n;
-                             Array.blit extension 0 lexBuffer.Buffer lexBuffer.BufferScanPos n;
-                             lexBuffer.BufferMaxScanLength <- lexBuffer.BufferScanLength + n); 
-                  fillAsync = 
-                    match asyncRead with 
-                    | None -> None
-                    | Some read -> 
-                         Some (fun lexBuffer -> 
-                                  async { 
-                                      let! n = read(extension,0,extension.Length)
-                                      lexBuffer.EnsureBufferSize n;
-                                      Array.blit extension 0 lexBuffer.Buffer lexBuffer.BufferScanPos n;
-                                      lexBuffer.BufferMaxScanLength <- lexBuffer.BufferScanLength + n }) }
-            new LexBuffer<_>(fillers)
-
-        // A full type signature is required on this method because it is used at more specific types within its own scope
-        static member FromFunction (f : 'char[] * int * int -> int) : LexBuffer<'char> =  LexBuffer<_>.FromReadFunctions(Some(f),None)
-        static member FromAsyncFunction (f : 'char[] * int * int -> Async<int>) : LexBuffer<'char> =  LexBuffer<_>.FromReadFunctions(None,Some(f))
-              
-        static member FromCharFunction f : LexBuffer<char> = 
-            LexBuffer<char>.FromFunction(fun (buff,start,len) -> 
-                let buff2 = Array.zeroCreate len
-                let n = f buff2 len 
-                Array.blit buff2 0 buff start len
-                n)
-        static member FromByteFunction f : LexBuffer<byte> = 
-            LexBuffer<byte>.FromFunction(fun (buff,start,len) -> 
-                let buff2 = Array.zeroCreate len
-                let n = f buff2 len 
-                Array.blit buff2 0 buff start len
-                n)
-
-        // A full type signature is required on this method because it is used at more specific types within its own scope
-        static member FromArray (s: 'char[]) : LexBuffer<'char> = 
-            let lexBuffer = 
-                new LexBuffer<_> 
-                    { fillSync = Some (fun _ -> ()); 
-                      fillAsync = Some (fun _ -> async { return () }) }
-            let buffer = Array.copy s 
-            lexBuffer.Buffer <- buffer;
-            lexBuffer.BufferMaxScanLength <- buffer.Length;
-            lexBuffer
-
-        static member FromBytes    (arr) = LexBuffer<byte>.FromArray(arr)
-        static member FromChars    (arr) = LexBuffer<char>.FromArray(arr) 
-        static member FromString (s:string) = LexBuffer<char>.FromChars (s.ToCharArray())
-
-        static member FromTextReader (tr:System.IO.TextReader)  : LexBuffer<char> = 
-           LexBuffer<char>.FromFunction(tr.Read) 
-
-        static member FromBinaryReader (br:System.IO.BinaryReader)  : LexBuffer<byte> = 
-           LexBuffer<byte>.FromFunction(br.Read) 
-
-        static member FromStream (stream:System.IO.Stream)  : LexBuffer<byte> = 
-           LexBuffer<byte>.FromReadFunctions(Some(stream.Read),Some(fun (buf,offset,len) -> stream.AsyncRead(buf,offset=offset,count=len))) 
-
-    module GenericImplFragments = 
-        let startInterpret(lexBuffer:LexBuffer<_>)= 
-            lexBuffer.BufferScanStart <- lexBuffer.BufferScanStart + lexBuffer.LexemeLength;
-            lexBuffer.BufferMaxScanLength <- lexBuffer.BufferMaxScanLength - lexBuffer.LexemeLength;
-            lexBuffer.BufferScanLength <- 0;
-            lexBuffer.LexemeLength <- 0;
-            lexBuffer.BufferAcceptAction <- -1;
-
-        let afterRefill (trans: uint16[] array,sentinel,lexBuffer:LexBuffer<_>,scanUntilSentinel,endOfScan,state,eofPos) = 
-            // end of file occurs if we couldn't extend the buffer 
-            if lexBuffer.BufferScanLength = lexBuffer.BufferMaxScanLength then  
-                let snew = int trans.[state].[eofPos] // == EOF 
-                if snew = sentinel then 
-                    endOfScan()
-                else 
-                    if lexBuffer.IsPastEndOfStream then failwith "End of file on lexing stream";
-                    lexBuffer.IsPastEndOfStream <- true;
-                    // Printf.printf "state %d --> %d on eof\n" state snew;
-                    scanUntilSentinel(lexBuffer,snew)
-            else 
-                scanUntilSentinel(lexBuffer, state)
-
-        let onAccept (lexBuffer:LexBuffer<_>,a) = 
-            lexBuffer.LexemeLength <- lexBuffer.BufferScanLength;
-            lexBuffer.BufferAcceptAction <- a;
-
-    open GenericImplFragments
-
-    [<Sealed>]
-#if INTERNALIZED_POWER_PACK
-    type internal AsciiTables(trans: uint16[] array, accept: uint16[]) =
-#else
-    type AsciiTables(trans: uint16[] array, accept: uint16[]) =
-#endif
-        let rec scanUntilSentinel(lexBuffer, state) =
-            let sentinel = 255 * 256 + 255 
-            // Return an endOfScan after consuming the input 
-            let a = int accept.[state] 
-            if a <> sentinel then 
-                onAccept (lexBuffer,a)
-            
-            if lexBuffer.BufferScanLength = lexBuffer.BufferMaxScanLength then 
-                lexBuffer.DiscardInput();
-                lexBuffer.RefillBuffer ();
-              // end of file occurs if we couldn't extend the buffer 
-                afterRefill (trans,sentinel,lexBuffer,scanUntilSentinel,lexBuffer.EndOfScan,state,256 (* == EOF *) )
-            else
-                // read a character - end the scan if there are no further transitions 
-                let inp = int(lexBuffer.Buffer.[lexBuffer.BufferScanPos])
-                let snew = int trans.[state].[inp] 
-                if snew = sentinel then 
-                    lexBuffer.EndOfScan()
-                else 
-                    lexBuffer.BufferScanLength <- lexBuffer.BufferScanLength + 1;
-                    // Printf.printf "state %d --> %d on '%c' (%d)\n" state snew (Char.chr inp) inp;
-                    scanUntilSentinel(lexBuffer, snew)
-            
-        /// Interpret tables for an ascii lexer generated by fslex. 
-        member tables.Interpret(initialState,lexBuffer : LexBuffer<byte>) = 
-            startInterpret(lexBuffer)
-            scanUntilSentinel(lexBuffer, initialState)
-
-        /// Interpret tables for an ascii lexer generated by fslex. 
-        member tables.AsyncInterpret(initialState,lexBuffer : LexBuffer<byte>) = 
-        
-            let rec scanUntilSentinel(lexBuffer,state) : Async<int> = 
-                async {  
-                    let sentinel = 255 * 256 + 255 
-                    // Return an endOfScan after consuming the input 
-                    let a = int accept.[state] 
-                    if a <> sentinel then 
-                        onAccept (lexBuffer,a)
-                    
-                    if lexBuffer.BufferScanLength = lexBuffer.BufferMaxScanLength then 
-                        lexBuffer.DiscardInput();
-                        do! lexBuffer.AsyncRefillBuffer ();
-                       // end of file occurs if we couldn't extend the buffer 
-                        return! afterRefill (trans,sentinel,lexBuffer,scanUntilSentinel,endOfScan,state,256 (* == EOF *) )
-                    else
-                        // read a character - end the scan if there are no further transitions 
-                        let inp = int(lexBuffer.Buffer.[lexBuffer.BufferScanPos])
-                        let snew = int trans.[state].[inp] 
-                        if snew = sentinel then 
-                            return! endOfScan()
-                        else 
-                            lexBuffer.BufferScanLength <- lexBuffer.BufferScanLength + 1;
-                            return! scanUntilSentinel(lexBuffer,snew)
-                }
-            and endOfScan() = 
-                async { return lexBuffer.EndOfScan() }
-            startInterpret(lexBuffer)
-            scanUntilSentinel(lexBuffer, initialState)
-
-
-        static member Create(trans,accept) = new AsciiTables(trans,accept)
-
-    [<Sealed>]
-#if INTERNALIZED_POWER_PACK
-    type internal UnicodeTables(trans: uint16[] array, accept: uint16[]) = 
-#else
-    type UnicodeTables(trans: uint16[] array, accept: uint16[]) = 
-#endif
-        let sentinel = 255 * 256 + 255 
-        let numUnicodeCategories = 30 
-        let numLowUnicodeChars = 128 
-        let numSpecificUnicodeChars = (trans.[0].Length - 1 - numLowUnicodeChars - numUnicodeCategories)/2
-        let lookupUnicodeCharacters (state,inp) = 
-            let inpAsInt = int inp
-            // Is it a fast ASCII character?
-            if inpAsInt < numLowUnicodeChars then 
-                int trans.[state].[inpAsInt]
-            else 
-                // Search for a specific unicode character
-                let baseForSpecificUnicodeChars = numLowUnicodeChars
-                let rec loop i = 
-                    if i >= numSpecificUnicodeChars then 
-                        // OK, if we failed then read the 'others' entry in the alphabet,
-                        // which covers all Unicode characters not covered in other
-                        // ways
-                        let baseForUnicodeCategories = numLowUnicodeChars+numSpecificUnicodeChars*2
-                        let unicodeCategory = System.Char.GetUnicodeCategory(inp)
-                        //System.Console.WriteLine("inp = {0}, unicodeCategory = {1}", [| box inp; box unicodeCategory |]);
-                        int trans.[state].[baseForUnicodeCategories + int32 unicodeCategory]
-                    else 
-                        // This is the specific unicode character
-                        let c = char (int trans.[state].[baseForSpecificUnicodeChars+i*2])
-                        //System.Console.WriteLine("c = {0}, inp = {1}, i = {2}", [| box c; box inp; box i |]);
-                        // OK, have we found the entry for a specific unicode character?
-                        if c = inp
-                        then int trans.[state].[baseForSpecificUnicodeChars+i*2+1]
-                        else loop(i+1)
-                
-                loop 0
-        let eofPos    = numLowUnicodeChars + 2*numSpecificUnicodeChars + numUnicodeCategories 
-        
-        let rec scanUntilSentinel(lexBuffer,state) =
-            // Return an endOfScan after consuming the input 
-            let a = int accept.[state] 
-            if a <> sentinel then 
-                onAccept(lexBuffer,a)
-            
-            if lexBuffer.BufferScanLength = lexBuffer.BufferMaxScanLength then 
-                lexBuffer.DiscardInput();
-                lexBuffer.RefillBuffer ();
-              // end of file occurs if we couldn't extend the buffer 
-                afterRefill (trans,sentinel,lexBuffer,scanUntilSentinel,lexBuffer.EndOfScan,state,eofPos)
-            else
-                // read a character - end the scan if there are no further transitions 
-                let inp = lexBuffer.Buffer.[lexBuffer.BufferScanPos]
-                
-                // Find the new state
-                let snew = lookupUnicodeCharacters (state,inp)
-
-                if snew = sentinel then 
-                    lexBuffer.EndOfScan()
-                else 
-                    lexBuffer.BufferScanLength <- lexBuffer.BufferScanLength + 1;
-                    // Printf.printf "state %d --> %d on '%c' (%d)\n" s snew (char inp) inp;
-                    scanUntilSentinel(lexBuffer,snew)
-                          
-        // Each row for the Unicode table has format 
-        //      128 entries for ASCII characters
-        //      A variable number of 2*UInt16 entries for SpecificUnicodeChars 
-        //      30 entries, one for each UnicodeCategory
-        //      1 entry for EOF
-
-        member tables.Interpret(initialState,lexBuffer : LexBuffer<char>) = 
-            startInterpret(lexBuffer)
-            scanUntilSentinel(lexBuffer, initialState)
-
-        member tables.AsyncInterpret(initialState,lexBuffer : LexBuffer<char>) = 
-
-            let rec scanUntilSentinel(lexBuffer, state) =
-                async {
-                    // Return an endOfScan after consuming the input 
-                    let a = int accept.[state] 
-                    if a <> sentinel then 
-                        onAccept(lexBuffer,a)
-                    
-                    if lexBuffer.BufferScanLength = lexBuffer.BufferMaxScanLength then 
-                        lexBuffer.DiscardInput();
-                        lexBuffer.RefillBuffer ();
-                        // end of file occurs if we couldn't extend the buffer 
-                        return! afterRefill (trans,sentinel,lexBuffer,scanUntilSentinel,endOfScan,state,eofPos)
-                    else
-                        // read a character - end the scan if there are no further transitions 
-                        let inp = lexBuffer.Buffer.[lexBuffer.BufferScanPos]
-                        
-                        // Find the new state
-                        let snew = lookupUnicodeCharacters (state,inp)
-
-                        if snew = sentinel then 
-                            return! endOfScan()
-                        else 
-                            lexBuffer.BufferScanLength <- lexBuffer.BufferScanLength + 1;
-                            return! scanUntilSentinel(lexBuffer, snew)
-                }
-            and endOfScan() = 
-                async { return lexBuffer.EndOfScan() } 
-            startInterpret(lexBuffer)
-            scanUntilSentinel(lexBuffer, initialState)
-
-        static member Create(trans,accept) = new UnicodeTables(trans,accept)
+// (c) Microsoft Corporation 2005-2009.
+
+#nowarn "47" // recursive initialization of LexBuffer
+
+
+#if INTERNALIZED_POWER_PACK
+namespace Internal.Utilities.Text.Lexing
+
+#else
+namespace Microsoft.FSharp.Text.Lexing 
+#endif
+
+    open System.Collections.Generic
+
+    // REVIEW: This type showed up on a parsing-intensive performance measurement. Consider whether it can be a struct-record later when we have this feature. -jomo
+#if INTERNALIZED_POWER_PACK
+    type internal Position = 
+#else
+    type Position = 
+#endif
+        { pos_fname : string;
+          pos_lnum : int;
+#if INTERNALIZED_POWER_PACK
+          pos_orig_lnum : int;
+#endif
+          pos_bol : int;
+          pos_cnum : int; }
+        member x.FileName = x.pos_fname
+        member x.Line = x.pos_lnum
+#if INTERNALIZED_POWER_PACK
+        member x.OriginalLine = x.pos_orig_lnum
+#endif
+        member x.Char = x.pos_cnum
+        member x.AbsoluteOffset = x.pos_cnum
+        member x.StartOfLine = x.pos_bol
+        member x.StartOfLineAbsoluteOffset = x.pos_bol
+        member x.Column = x.pos_cnum - x.pos_bol
+        member pos.NextLine = 
+            { pos with 
+#if INTERNALIZED_POWER_PACK
+                    pos_orig_lnum = pos.OriginalLine + 1;
+#endif
+                    pos_lnum = pos.Line+1; 
+                    pos_bol = pos.AbsoluteOffset }
+        member pos.EndOfToken(n) = {pos with pos_cnum=pos.pos_cnum + n }
+        member pos.AsNewLinePos() = pos.NextLine
+        member pos.ShiftColumnBy(by) = {pos with pos_cnum = pos.pos_cnum + by}
+        static member Empty = 
+            { pos_fname=""; 
+              pos_lnum= 0; 
+#if INTERNALIZED_POWER_PACK
+              pos_orig_lnum = 0;
+#endif
+              pos_bol= 0; 
+              pos_cnum=0 }
+        static member FirstLine(filename) = 
+            { pos_fname=filename; 
+#if INTERNALIZED_POWER_PACK
+              pos_orig_lnum = 1;
+#endif
+              pos_lnum= 1; 
+              pos_bol= 0; 
+              pos_cnum=0 }
+
+#if INTERNALIZED_POWER_PACK
+    type internal LexBufferFiller<'char> = 
+#else
+    type LexBufferFiller<'char> = 
+#endif
+        { fillSync : (LexBuffer<'char> -> unit) option
+          fillAsync : (LexBuffer<'char> -> Async<unit>) option } 
+        
+    and [<Sealed>]
+#if INTERNALIZED_POWER_PACK
+        internal LexBuffer<'char>(filler: LexBufferFiller<'char>) as this = 
+#else
+        LexBuffer<'char>(filler: LexBufferFiller<'char>) as this = 
+#endif
+        let context = new Dictionary<string,obj>(1) in 
+        let extendBufferSync = (fun () -> match filler.fillSync with Some refill -> refill this | None -> invalidOp "attempt to read synchronously from an asynchronous lex buffer")
+        let extendBufferAsync = (fun () -> match filler.fillAsync with Some refill -> refill this | None -> invalidOp "attempt to read asynchronously from a synchronous lex buffer")
+        let mutable buffer=[||];
+        /// number of valid charactes beyond bufferScanStart 
+        let mutable bufferMaxScanLength=0;
+        /// count into the buffer when scanning 
+        let mutable bufferScanStart=0;
+        /// number of characters scanned so far 
+        let mutable bufferScanLength=0;
+        /// length of the scan at the last accepting state 
+        let mutable lexemeLength=0;
+        /// action related to the last accepting state 
+        let mutable bufferAcceptAction=0;
+        let mutable eof = false;
+        let mutable startPos = Position.Empty ;
+        let mutable endPos = Position.Empty
+
+        // Throw away all the input besides the lexeme 
+              
+        let discardInput () = 
+            let keep = Array.sub buffer bufferScanStart bufferScanLength
+            let nkeep = keep.Length 
+            Array.blit keep 0 buffer 0 nkeep;
+            bufferScanStart <- 0;
+            bufferMaxScanLength <- nkeep
+                 
+              
+        member lexbuf.EndOfScan () : int =
+            // Printf.eprintf "endOfScan, lexBuffer.lexemeLength = %d\n" lexBuffer.lexemeLength;
+            if bufferAcceptAction < 0 then 
+                failwith "unrecognized input"
+
+            //  Printf.printf "endOfScan %d state %d on unconsumed input '%c' (%d)\n" a s (Char.chr inp) inp;
+            //   Printf.eprintf "accept, lexeme = %s\n" (lexeme lexBuffer); 
+            lexbuf.StartPos <- endPos;
+            lexbuf.EndPos <- endPos.EndOfToken(lexbuf.LexemeLength);
+            bufferAcceptAction
+
+        member lexbuf.StartPos
+           with get() = startPos
+           and  set(b) =  startPos <- b
+           
+        member lexbuf.EndPos 
+           with get() = endPos
+           and  set(b) =  endPos <- b
+
+        member lexbuf.Lexeme         = Array.sub buffer bufferScanStart lexemeLength
+        member lexbuf.LexemeChar(n)  = buffer.[n+bufferScanStart]
+        
+        member lexbuf.BufferLocalStore = (context :> IDictionary<_,_>)
+        member lexbuf.LexemeLength        with get() : int = lexemeLength    and set v = lexemeLength <- v
+        member internal lexbuf.Buffer              with get() : 'char[] = buffer              and set v = buffer <- v
+        member internal lexbuf.BufferMaxScanLength with get() = bufferMaxScanLength and set v = bufferMaxScanLength <- v
+        member internal lexbuf.BufferScanLength    with get() = bufferScanLength    and set v = bufferScanLength <- v
+        member internal lexbuf.BufferScanStart     with get() : int = bufferScanStart     and set v = bufferScanStart <- v
+        member internal lexbuf.BufferAcceptAction  with get() = bufferAcceptAction  and set v = bufferAcceptAction <- v
+        member internal lexbuf.RefillBuffer = extendBufferSync
+        member internal lexbuf.AsyncRefillBuffer = extendBufferAsync
+
+        static member LexemeString(lexbuf:LexBuffer<char>) = 
+            new System.String(lexbuf.Buffer,lexbuf.BufferScanStart,lexbuf.LexemeLength)
+
+        member lexbuf.IsPastEndOfStream 
+           with get() = eof
+           and  set(b) =  eof <- b
+
+        member lexbuf.DiscardInput() = discardInput ()
+
+        member x.BufferScanPos = bufferScanStart + bufferScanLength
+
+        member lexbuf.EnsureBufferSize n = 
+            if lexbuf.BufferScanPos + n >= buffer.Length then 
+                let repl = Array.zeroCreate (lexbuf.BufferScanPos + n) 
+                Array.blit buffer bufferScanStart repl bufferScanStart bufferScanLength;
+                buffer <- repl
+
+        static member FromReadFunctions (syncRead : ('char[] * int * int -> int) option, asyncRead : ('char[] * int * int -> Async<int>) option) : LexBuffer<'char> = 
+            let extension= Array.zeroCreate 4096
+            let fillers = 
+                { fillSync = 
+                    match syncRead with 
+                    | None -> None
+                    | Some read -> 
+                         Some (fun lexBuffer -> 
+                             let n = read(extension,0,extension.Length)
+                             lexBuffer.EnsureBufferSize n;
+                             Array.blit extension 0 lexBuffer.Buffer lexBuffer.BufferScanPos n;
+                             lexBuffer.BufferMaxScanLength <- lexBuffer.BufferScanLength + n); 
+                  fillAsync = 
+                    match asyncRead with 
+                    | None -> None
+                    | Some read -> 
+                         Some (fun lexBuffer -> 
+                                  async { 
+                                      let! n = read(extension,0,extension.Length)
+                                      lexBuffer.EnsureBufferSize n;
+                                      Array.blit extension 0 lexBuffer.Buffer lexBuffer.BufferScanPos n;
+                                      lexBuffer.BufferMaxScanLength <- lexBuffer.BufferScanLength + n }) }
+            new LexBuffer<_>(fillers)
+
+        // A full type signature is required on this method because it is used at more specific types within its own scope
+        static member FromFunction (f : 'char[] * int * int -> int) : LexBuffer<'char> =  LexBuffer<_>.FromReadFunctions(Some(f),None)
+        static member FromAsyncFunction (f : 'char[] * int * int -> Async<int>) : LexBuffer<'char> =  LexBuffer<_>.FromReadFunctions(None,Some(f))
+              
+        static member FromCharFunction f : LexBuffer<char> = 
+            LexBuffer<char>.FromFunction(fun (buff,start,len) -> 
+                let buff2 = Array.zeroCreate len
+                let n = f buff2 len 
+                Array.blit buff2 0 buff start len
+                n)
+        static member FromByteFunction f : LexBuffer<byte> = 
+            LexBuffer<byte>.FromFunction(fun (buff,start,len) -> 
+                let buff2 = Array.zeroCreate len
+                let n = f buff2 len 
+                Array.blit buff2 0 buff start len
+                n)
+
+        // A full type signature is required on this method because it is used at more specific types within its own scope
+        static member FromArray (s: 'char[]) : LexBuffer<'char> = 
+            let lexBuffer = 
+                new LexBuffer<_> 
+                    { fillSync = Some (fun _ -> ()); 
+                      fillAsync = Some (fun _ -> async { return () }) }
+            let buffer = Array.copy s 
+            lexBuffer.Buffer <- buffer;
+            lexBuffer.BufferMaxScanLength <- buffer.Length;
+            lexBuffer
+
+        static member FromBytes    (arr) = LexBuffer<byte>.FromArray(arr)
+        static member FromChars    (arr) = LexBuffer<char>.FromArray(arr) 
+        static member FromString (s:string) = LexBuffer<char>.FromChars (s.ToCharArray())
+
+        static member FromTextReader (tr:System.IO.TextReader)  : LexBuffer<char> = 
+           LexBuffer<char>.FromFunction(tr.Read) 
+
+        static member FromBinaryReader (br:System.IO.BinaryReader)  : LexBuffer<byte> = 
+           LexBuffer<byte>.FromFunction(br.Read) 
+
+        static member FromStream (stream:System.IO.Stream)  : LexBuffer<byte> = 
+           LexBuffer<byte>.FromReadFunctions(Some(stream.Read),Some(fun (buf,offset,len) -> stream.AsyncRead(buf,offset=offset,count=len))) 
+
+    module GenericImplFragments = 
+        let startInterpret(lexBuffer:LexBuffer<_>)= 
+            lexBuffer.BufferScanStart <- lexBuffer.BufferScanStart + lexBuffer.LexemeLength;
+            lexBuffer.BufferMaxScanLength <- lexBuffer.BufferMaxScanLength - lexBuffer.LexemeLength;
+            lexBuffer.BufferScanLength <- 0;
+            lexBuffer.LexemeLength <- 0;
+            lexBuffer.BufferAcceptAction <- -1;
+
+        let afterRefill (trans: uint16[] array,sentinel,lexBuffer:LexBuffer<_>,scanUntilSentinel,endOfScan,state,eofPos) = 
+            // end of file occurs if we couldn't extend the buffer 
+            if lexBuffer.BufferScanLength = lexBuffer.BufferMaxScanLength then  
+                let snew = int trans.[state].[eofPos] // == EOF 
+                if snew = sentinel then 
+                    endOfScan()
+                else 
+                    if lexBuffer.IsPastEndOfStream then failwith "End of file on lexing stream";
+                    lexBuffer.IsPastEndOfStream <- true;
+                    // Printf.printf "state %d --> %d on eof\n" state snew;
+                    scanUntilSentinel(lexBuffer,snew)
+            else 
+                scanUntilSentinel(lexBuffer, state)
+
+        let onAccept (lexBuffer:LexBuffer<_>,a) = 
+            lexBuffer.LexemeLength <- lexBuffer.BufferScanLength;
+            lexBuffer.BufferAcceptAction <- a;
+
+    open GenericImplFragments
+
+    [<Sealed>]
+#if INTERNALIZED_POWER_PACK
+    type internal AsciiTables(trans: uint16[] array, accept: uint16[]) =
+#else
+    type AsciiTables(trans: uint16[] array, accept: uint16[]) =
+#endif
+        let rec scanUntilSentinel(lexBuffer, state) =
+            let sentinel = 255 * 256 + 255 
+            // Return an endOfScan after consuming the input 
+            let a = int accept.[state] 
+            if a <> sentinel then 
+                onAccept (lexBuffer,a)
+            
+            if lexBuffer.BufferScanLength = lexBuffer.BufferMaxScanLength then 
+                lexBuffer.DiscardInput();
+                lexBuffer.RefillBuffer ();
+              // end of file occurs if we couldn't extend the buffer 
+                afterRefill (trans,sentinel,lexBuffer,scanUntilSentinel,lexBuffer.EndOfScan,state,256 (* == EOF *) )
+            else
+                // read a character - end the scan if there are no further transitions 
+                let inp = int(lexBuffer.Buffer.[lexBuffer.BufferScanPos])
+                let snew = int trans.[state].[inp] 
+                if snew = sentinel then 
+                    lexBuffer.EndOfScan()
+                else 
+                    lexBuffer.BufferScanLength <- lexBuffer.BufferScanLength + 1;
+                    // Printf.printf "state %d --> %d on '%c' (%d)\n" state snew (Char.chr inp) inp;
+                    scanUntilSentinel(lexBuffer, snew)
+            
+        /// Interpret tables for an ascii lexer generated by fslex. 
+        member tables.Interpret(initialState,lexBuffer : LexBuffer<byte>) = 
+            startInterpret(lexBuffer)
+            scanUntilSentinel(lexBuffer, initialState)
+
+        /// Interpret tables for an ascii lexer generated by fslex. 
+        member tables.AsyncInterpret(initialState,lexBuffer : LexBuffer<byte>) = 
+        
+            let rec scanUntilSentinel(lexBuffer,state) : Async<int> = 
+                async {  
+                    let sentinel = 255 * 256 + 255 
+                    // Return an endOfScan after consuming the input 
+                    let a = int accept.[state] 
+                    if a <> sentinel then 
+                        onAccept (lexBuffer,a)
+                    
+                    if lexBuffer.BufferScanLength = lexBuffer.BufferMaxScanLength then 
+                        lexBuffer.DiscardInput();
+                        do! lexBuffer.AsyncRefillBuffer ();
+                       // end of file occurs if we couldn't extend the buffer 
+                        return! afterRefill (trans,sentinel,lexBuffer,scanUntilSentinel,endOfScan,state,256 (* == EOF *) )
+                    else
+                        // read a character - end the scan if there are no further transitions 
+                        let inp = int(lexBuffer.Buffer.[lexBuffer.BufferScanPos])
+                        let snew = int trans.[state].[inp] 
+                        if snew = sentinel then 
+                            return! endOfScan()
+                        else 
+                            lexBuffer.BufferScanLength <- lexBuffer.BufferScanLength + 1;
+                            return! scanUntilSentinel(lexBuffer,snew)
+                }
+            and endOfScan() = 
+                async { return lexBuffer.EndOfScan() }
+            startInterpret(lexBuffer)
+            scanUntilSentinel(lexBuffer, initialState)
+
+
+        static member Create(trans,accept) = new AsciiTables(trans,accept)
+
+    [<Sealed>]
+#if INTERNALIZED_POWER_PACK
+    type internal UnicodeTables(trans: uint16[] array, accept: uint16[]) = 
+#else
+    type UnicodeTables(trans: uint16[] array, accept: uint16[]) = 
+#endif
+        let sentinel = 255 * 256 + 255 
+        let numUnicodeCategories = 30 
+        let numLowUnicodeChars = 128 
+        let numSpecificUnicodeChars = (trans.[0].Length - 1 - numLowUnicodeChars - numUnicodeCategories)/2
+        let lookupUnicodeCharacters (state,inp) = 
+            let inpAsInt = int inp
+            // Is it a fast ASCII character?
+            if inpAsInt < numLowUnicodeChars then 
+                int trans.[state].[inpAsInt]
+            else 
+                // Search for a specific unicode character
+                let baseForSpecificUnicodeChars = numLowUnicodeChars
+                let rec loop i = 
+                    if i >= numSpecificUnicodeChars then 
+                        // OK, if we failed then read the 'others' entry in the alphabet,
+                        // which covers all Unicode characters not covered in other
+                        // ways
+                        let baseForUnicodeCategories = numLowUnicodeChars+numSpecificUnicodeChars*2
+                        let unicodeCategory = System.Char.GetUnicodeCategory(inp)
+                        //System.Console.WriteLine("inp = {0}, unicodeCategory = {1}", [| box inp; box unicodeCategory |]);
+                        int trans.[state].[baseForUnicodeCategories + int32 unicodeCategory]
+                    else 
+                        // This is the specific unicode character
+                        let c = char (int trans.[state].[baseForSpecificUnicodeChars+i*2])
+                        //System.Console.WriteLine("c = {0}, inp = {1}, i = {2}", [| box c; box inp; box i |]);
+                        // OK, have we found the entry for a specific unicode character?
+                        if c = inp
+                        then int trans.[state].[baseForSpecificUnicodeChars+i*2+1]
+                        else loop(i+1)
+                
+                loop 0
+        let eofPos    = numLowUnicodeChars + 2*numSpecificUnicodeChars + numUnicodeCategories 
+        
+        let rec scanUntilSentinel(lexBuffer,state) =
+            // Return an endOfScan after consuming the input 
+            let a = int accept.[state] 
+            if a <> sentinel then 
+                onAccept(lexBuffer,a)
+            
+            if lexBuffer.BufferScanLength = lexBuffer.BufferMaxScanLength then 
+                lexBuffer.DiscardInput();
+                lexBuffer.RefillBuffer ();
+              // end of file occurs if we couldn't extend the buffer 
+                afterRefill (trans,sentinel,lexBuffer,scanUntilSentinel,lexBuffer.EndOfScan,state,eofPos)
+            else
+                // read a character - end the scan if there are no further transitions 
+                let inp = lexBuffer.Buffer.[lexBuffer.BufferScanPos]
+                
+                // Find the new state
+                let snew = lookupUnicodeCharacters (state,inp)
+
+                if snew = sentinel then 
+                    lexBuffer.EndOfScan()
+                else 
+                    lexBuffer.BufferScanLength <- lexBuffer.BufferScanLength + 1;
+                    // Printf.printf "state %d --> %d on '%c' (%d)\n" s snew (char inp) inp;
+                    scanUntilSentinel(lexBuffer,snew)
+                          
+        // Each row for the Unicode table has format 
+        //      128 entries for ASCII characters
+        //      A variable number of 2*UInt16 entries for SpecificUnicodeChars 
+        //      30 entries, one for each UnicodeCategory
+        //      1 entry for EOF
+
+        member tables.Interpret(initialState,lexBuffer : LexBuffer<char>) = 
+            startInterpret(lexBuffer)
+            scanUntilSentinel(lexBuffer, initialState)
+
+        member tables.AsyncInterpret(initialState,lexBuffer : LexBuffer<char>) = 
+
+            let rec scanUntilSentinel(lexBuffer, state) =
+                async {
+                    // Return an endOfScan after consuming the input 
+                    let a = int accept.[state] 
+                    if a <> sentinel then 
+                        onAccept(lexBuffer,a)
+                    
+                    if lexBuffer.BufferScanLength = lexBuffer.BufferMaxScanLength then 
+                        lexBuffer.DiscardInput();
+                        lexBuffer.RefillBuffer ();
+                        // end of file occurs if we couldn't extend the buffer 
+                        return! afterRefill (trans,sentinel,lexBuffer,scanUntilSentinel,endOfScan,state,eofPos)
+                    else
+                        // read a character - end the scan if there are no further transitions 
+                        let inp = lexBuffer.Buffer.[lexBuffer.BufferScanPos]
+                        
+                        // Find the new state
+                        let snew = lookupUnicodeCharacters (state,inp)
+
+                        if snew = sentinel then 
+                            return! endOfScan()
+                        else 
+                            lexBuffer.BufferScanLength <- lexBuffer.BufferScanLength + 1;
+                            return! scanUntilSentinel(lexBuffer, snew)
+                }
+            and endOfScan() = 
+                async { return lexBuffer.EndOfScan() } 
+            startInterpret(lexBuffer)
+            scanUntilSentinel(lexBuffer, initialState)
+
+        static member Create(trans,accept) = new UnicodeTables(trans,accept)
--- fsharp-3.1.1.26+dfsg2.orig/FSharp.PowerPack/Lexing.fsi
+++ fsharp-3.1.1.26+dfsg2/FSharp.PowerPack/Lexing.fsi
@@ -1,151 +1,151 @@
-//==========================================================================
-// LexBuffers are for use with automatically generated lexical analyzers,
-// in particular those produced by 'fslex'.
-//
-// (c) Microsoft Corporation 2005-2008.
-//===========================================================================
-
-#if INTERNALIZED_POWER_PACK
-namespace Internal.Utilities.Text.Lexing
-#else
-namespace Microsoft.FSharp.Text.Lexing 
-#endif
-
-open System.Collections.Generic
-
-/// Position information stored for lexing tokens
-//
-// Note: this is an OCaml compat record type. 
-#if INTERNALIZED_POWER_PACK
-type internal Position = 
-#else
-type Position = 
-#endif
-    { /// The file name for the position
-      pos_fname: string;
-      /// The line number for the position
-      pos_lnum: int;
-#if INTERNALIZED_POWER_PACK
-      /// The line number for the position in the original source file
-      pos_orig_lnum : int;
-#endif
-      /// The absolute offset of the beginning of the line
-      pos_bol: int;
-      /// The absolute offset of the column for the position
-      pos_cnum: int; }
-     /// The file name associated with the input stream.
-     member FileName : string
-     /// The line number in the input stream, assuming fresh positions have been updated 
-     /// using AsNewLinePos() and by modifying the EndPos property of the LexBuffer.
-     member Line : int
-#if INTERNALIZED_POWER_PACK
-     /// The line number for the position in the input stream, assuming fresh positions have been updated 
-     /// using AsNewLinePos()
-     member OriginalLine : int
-#endif
-     [<System.ObsoleteAttribute("Use the AbsoluteOffset property instead")>]
-     member Char : int
-     /// The character number in the input stream
-     member AbsoluteOffset : int
-     /// Return absolute offset of the start of the line marked by the position
-     member StartOfLineAbsoluteOffset : int
-     /// Return the column number marked by the position, i.e. the difference between the AbsoluteOffset and the StartOfLineAbsoluteOffset
-     member Column : int
-     // Given a position just beyond the end of a line, return a position at the start of the next line
-     member NextLine : Position     
-     
-     /// Given a position at the start of a token of length n, return a position just beyond the end of the token
-     member EndOfToken: n:int -> Position
-     /// Gives a position shifted by specified number of characters
-     member ShiftColumnBy: by:int -> Position
-     
-     [<System.ObsoleteAttribute("Consider using the NextLine property instead")>]
-     member AsNewLinePos : unit -> Position
-     
-     /// Get an arbitrary position, with the empty string as filename, and  
-     static member Empty : Position
-
-     /// Get a position corresponding to the first line (line number 1) in a given file
-     static member FirstLine : filename:string -> Position
-    
-[<Sealed>]
-#if INTERNALIZED_POWER_PACK
-type internal LexBuffer<'char> =
-#else
-/// Input buffers consumed by lexers generated by <c>fslex.exe </c>
-type LexBuffer<'char> =
-#endif
-    /// The start position for the lexeme
-    member StartPos: Position with get,set
-    /// The end position for the lexeme
-    member EndPos: Position with get,set
-    /// The matched string 
-    member Lexeme: 'char array
-    
-    /// Fast helper to turn the matched characters into a string, avoiding an intermediate array
-    static member LexemeString : LexBuffer<char> -> string
-    
-    /// The length of the matched string 
-    member LexemeLength: int
-    /// Fetch a particular character in the matched string 
-    member LexemeChar: int -> 'char
-
-    /// Dynamically typed, non-lexically scoped parameter table
-    member BufferLocalStore : IDictionary<string,obj>
-    
-    /// True if the refill of the buffer ever failed , or if explicitly set to true.
-    member IsPastEndOfStream: bool with get,set
-    /// Remove all input, though don't discard the current lexeme 
-    member DiscardInput: unit -> unit
-
-    /// Create a lex buffer suitable for byte lexing that reads characters from the given array
-    static member FromBytes: byte[] -> LexBuffer<byte>
-    /// Create a lex buffer suitable for Unicode lexing that reads characters from the given array
-    static member FromChars: char[] -> LexBuffer<char>
-    /// Create a lex buffer suitable for Unicode lexing that reads characters from the given string
-    static member FromString: string -> LexBuffer<char>
-    /// Create a lex buffer that reads character or byte inputs by using the given function
-    static member FromFunction: ('char[] * int * int -> int) -> LexBuffer<'char>
-    /// Create a lex buffer that asynchronously reads character or byte inputs by using the given function
-    static member FromAsyncFunction: ('char[] * int * int -> Async<int>) -> LexBuffer<'char>
-
-
-    [<System.Obsolete("Use LexBuffer<char>.FromFunction instead")>]
-    static member FromCharFunction: (char[] -> int -> int) -> LexBuffer<char>
-    [<System.Obsolete("Use LexBuffer<byte>.FromFunction instead")>]
-    static member FromByteFunction: (byte[] -> int -> int) -> LexBuffer<byte>
-
-    /// Create a lex buffer suitable for use with a Unicode lexer that reads character inputs from the given text reader
-    static member FromTextReader: System.IO.TextReader -> LexBuffer<char>
-    /// Create a lex buffer suitable for use with ASCII byte lexing that reads byte inputs from the given binary reader
-    static member FromBinaryReader: System.IO.BinaryReader -> LexBuffer<byte>
-
-
-/// The type of tables for an ascii lexer generated by fslex. 
-[<Sealed>]
-#if INTERNALIZED_POWER_PACK
-type internal AsciiTables =
-#else
-type AsciiTables =
-#endif
-    static member Create : uint16[] array * uint16[] -> AsciiTables
-    /// Interpret tables for an ascii lexer generated by fslex. 
-    member Interpret:  initialState:int * LexBuffer<byte>  -> int
-    /// Interpret tables for an ascii lexer generated by fslex, processing input asynchronously
-    member AsyncInterpret:  initialState:int * LexBuffer<byte> -> Async<int>
-
-
-/// The type of tables for an unicode lexer generated by fslex. 
-[<Sealed>]
-#if INTERNALIZED_POWER_PACK
-type internal UnicodeTables =
-#else
-type UnicodeTables =
-#endif
-    static member Create : uint16[] array * uint16[] -> UnicodeTables
-    /// Interpret tables for a unicode lexer generated by fslex. 
-    member Interpret:  initialState:int * LexBuffer<char> -> int
-
-    /// Interpret tables for a unicode lexer generated by fslex, processing input asynchronously
-    member AsyncInterpret:  initialState:int * LexBuffer<char> -> Async<int>
-
+//==========================================================================
+// LexBuffers are for use with automatically generated lexical analyzers,
+// in particular those produced by 'fslex'.
+//
+// (c) Microsoft Corporation 2005-2008.
+//===========================================================================
+
+#if INTERNALIZED_POWER_PACK
+namespace Internal.Utilities.Text.Lexing
+#else
+namespace Microsoft.FSharp.Text.Lexing 
+#endif
+
+open System.Collections.Generic
+
+/// Position information stored for lexing tokens
+//
+// Note: this is an OCaml compat record type. 
+#if INTERNALIZED_POWER_PACK
+type internal Position = 
+#else
+type Position = 
+#endif
+    { /// The file name for the position
+      pos_fname: string;
+      /// The line number for the position
+      pos_lnum: int;
+#if INTERNALIZED_POWER_PACK
+      /// The line number for the position in the original source file
+      pos_orig_lnum : int;
+#endif
+      /// The absolute offset of the beginning of the line
+      pos_bol: int;
+      /// The absolute offset of the column for the position
+      pos_cnum: int; }
+     /// The file name associated with the input stream.
+     member FileName : string
+     /// The line number in the input stream, assuming fresh positions have been updated 
+     /// using AsNewLinePos() and by modifying the EndPos property of the LexBuffer.
+     member Line : int
+#if INTERNALIZED_POWER_PACK
+     /// The line number for the position in the input stream, assuming fresh positions have been updated 
+     /// using AsNewLinePos()
+     member OriginalLine : int
+#endif
+     [<System.ObsoleteAttribute("Use the AbsoluteOffset property instead")>]
+     member Char : int
+     /// The character number in the input stream
+     member AbsoluteOffset : int
+     /// Return absolute offset of the start of the line marked by the position
+     member StartOfLineAbsoluteOffset : int
+     /// Return the column number marked by the position, i.e. the difference between the AbsoluteOffset and the StartOfLineAbsoluteOffset
+     member Column : int
+     // Given a position just beyond the end of a line, return a position at the start of the next line
+     member NextLine : Position     
+     
+     /// Given a position at the start of a token of length n, return a position just beyond the end of the token
+     member EndOfToken: n:int -> Position
+     /// Gives a position shifted by specified number of characters
+     member ShiftColumnBy: by:int -> Position
+     
+     [<System.ObsoleteAttribute("Consider using the NextLine property instead")>]
+     member AsNewLinePos : unit -> Position
+     
+     /// Get an arbitrary position, with the empty string as filename, and  
+     static member Empty : Position
+
+     /// Get a position corresponding to the first line (line number 1) in a given file
+     static member FirstLine : filename:string -> Position
+    
+[<Sealed>]
+#if INTERNALIZED_POWER_PACK
+type internal LexBuffer<'char> =
+#else
+/// Input buffers consumed by lexers generated by <c>fslex.exe </c>
+type LexBuffer<'char> =
+#endif
+    /// The start position for the lexeme
+    member StartPos: Position with get,set
+    /// The end position for the lexeme
+    member EndPos: Position with get,set
+    /// The matched string 
+    member Lexeme: 'char array
+    
+    /// Fast helper to turn the matched characters into a string, avoiding an intermediate array
+    static member LexemeString : LexBuffer<char> -> string
+    
+    /// The length of the matched string 
+    member LexemeLength: int
+    /// Fetch a particular character in the matched string 
+    member LexemeChar: int -> 'char
+
+    /// Dynamically typed, non-lexically scoped parameter table
+    member BufferLocalStore : IDictionary<string,obj>
+    
+    /// True if the refill of the buffer ever failed , or if explicitly set to true.
+    member IsPastEndOfStream: bool with get,set
+    /// Remove all input, though don't discard the current lexeme 
+    member DiscardInput: unit -> unit
+
+    /// Create a lex buffer suitable for byte lexing that reads characters from the given array
+    static member FromBytes: byte[] -> LexBuffer<byte>
+    /// Create a lex buffer suitable for Unicode lexing that reads characters from the given array
+    static member FromChars: char[] -> LexBuffer<char>
+    /// Create a lex buffer suitable for Unicode lexing that reads characters from the given string
+    static member FromString: string -> LexBuffer<char>
+    /// Create a lex buffer that reads character or byte inputs by using the given function
+    static member FromFunction: ('char[] * int * int -> int) -> LexBuffer<'char>
+    /// Create a lex buffer that asynchronously reads character or byte inputs by using the given function
+    static member FromAsyncFunction: ('char[] * int * int -> Async<int>) -> LexBuffer<'char>
+
+
+    [<System.Obsolete("Use LexBuffer<char>.FromFunction instead")>]
+    static member FromCharFunction: (char[] -> int -> int) -> LexBuffer<char>
+    [<System.Obsolete("Use LexBuffer<byte>.FromFunction instead")>]
+    static member FromByteFunction: (byte[] -> int -> int) -> LexBuffer<byte>
+
+    /// Create a lex buffer suitable for use with a Unicode lexer that reads character inputs from the given text reader
+    static member FromTextReader: System.IO.TextReader -> LexBuffer<char>
+    /// Create a lex buffer suitable for use with ASCII byte lexing that reads byte inputs from the given binary reader
+    static member FromBinaryReader: System.IO.BinaryReader -> LexBuffer<byte>
+
+
+/// The type of tables for an ascii lexer generated by fslex. 
+[<Sealed>]
+#if INTERNALIZED_POWER_PACK
+type internal AsciiTables =
+#else
+type AsciiTables =
+#endif
+    static member Create : uint16[] array * uint16[] -> AsciiTables
+    /// Interpret tables for an ascii lexer generated by fslex. 
+    member Interpret:  initialState:int * LexBuffer<byte>  -> int
+    /// Interpret tables for an ascii lexer generated by fslex, processing input asynchronously
+    member AsyncInterpret:  initialState:int * LexBuffer<byte> -> Async<int>
+
+
+/// The type of tables for an unicode lexer generated by fslex. 
+[<Sealed>]
+#if INTERNALIZED_POWER_PACK
+type internal UnicodeTables =
+#else
+type UnicodeTables =
+#endif
+    static member Create : uint16[] array * uint16[] -> UnicodeTables
+    /// Interpret tables for a unicode lexer generated by fslex. 
+    member Interpret:  initialState:int * LexBuffer<char> -> int
+
+    /// Interpret tables for a unicode lexer generated by fslex, processing input asynchronously
+    member AsyncInterpret:  initialState:int * LexBuffer<char> -> Async<int>
+
--- fsharp-3.1.1.26+dfsg2.orig/FSharp.PowerPack/Measure.fs
+++ fsharp-3.1.1.26+dfsg2/FSharp.PowerPack/Measure.fs
@@ -1,15 +1,15 @@
-// (c) Microsoft Corporation 2005-2009. 
-
-
-namespace Microsoft.FSharp.Math
-
-#nowarn "42"
-
-module Measure =
-
-    let infinity<[<Measure>] 'u> : float<'u> = LanguagePrimitives.FloatWithMeasure System.Double.PositiveInfinity
-    let nan<[<Measure>] 'u> : float<'u> = LanguagePrimitives.FloatWithMeasure System.Double.NaN
-
-    let infinityf<[<Measure>] 'u> : float32<'u> = LanguagePrimitives.Float32WithMeasure System.Single.PositiveInfinity
-    let nanf<[<Measure>] 'u> : float32<'u> = LanguagePrimitives.Float32WithMeasure System.Single.NaN
-
+// (c) Microsoft Corporation 2005-2009. 
+
+
+namespace Microsoft.FSharp.Math
+
+#nowarn "42"
+
+module Measure =
+
+    let infinity<[<Measure>] 'u> : float<'u> = LanguagePrimitives.FloatWithMeasure System.Double.PositiveInfinity
+    let nan<[<Measure>] 'u> : float<'u> = LanguagePrimitives.FloatWithMeasure System.Double.NaN
+
+    let infinityf<[<Measure>] 'u> : float32<'u> = LanguagePrimitives.Float32WithMeasure System.Single.PositiveInfinity
+    let nanf<[<Measure>] 'u> : float32<'u> = LanguagePrimitives.Float32WithMeasure System.Single.NaN
+
--- fsharp-3.1.1.26+dfsg2.orig/FSharp.PowerPack/Measure.fsi
+++ fsharp-3.1.1.26+dfsg2/FSharp.PowerPack/Measure.fsi
@@ -1,25 +1,25 @@
-// (c) Microsoft Corporation 2005-2009. 
-
-
-namespace Microsoft.FSharp.Math
-
-#nowarn "42"
-
-module Measure =
-
-    /// <summary>Version of <c>System.Double.PositiveInfinity</c> that is generic in its units-of-measure</summary>
-    [<GeneralizableValue>]
-    val infinity<[<Measure>] 'u> : float<'u>
-
-    /// <summary>Version of <c>System.Double.NaN</c> that is generic in its units-of-measure</summary>
-    [<GeneralizableValue>]
-    val nan<[<Measure>] 'u> : float<'u> 
-
-    /// <summary>Version of <c>System.Single.PositiveInfinity</c> that is generic in its units-of-measure</summary>
-    [<GeneralizableValue>]
-    val infinityf<[<Measure>] 'u> : float32<'u> 
-
-    /// <summary>Version of <c>System.Single.NaN</c> that is generic in its units-of-measure</summary>
-    [<GeneralizableValue>]
-    val nanf<[<Measure>] 'u> : float32<'u>
-
+// (c) Microsoft Corporation 2005-2009. 
+
+
+namespace Microsoft.FSharp.Math
+
+#nowarn "42"
+
+module Measure =
+
+    /// <summary>Version of <c>System.Double.PositiveInfinity</c> that is generic in its units-of-measure</summary>
+    [<GeneralizableValue>]
+    val infinity<[<Measure>] 'u> : float<'u>
+
+    /// <summary>Version of <c>System.Double.NaN</c> that is generic in its units-of-measure</summary>
+    [<GeneralizableValue>]
+    val nan<[<Measure>] 'u> : float<'u> 
+
+    /// <summary>Version of <c>System.Single.PositiveInfinity</c> that is generic in its units-of-measure</summary>
+    [<GeneralizableValue>]
+    val infinityf<[<Measure>] 'u> : float32<'u> 
+
+    /// <summary>Version of <c>System.Single.NaN</c> that is generic in its units-of-measure</summary>
+    [<GeneralizableValue>]
+    val nanf<[<Measure>] 'u> : float32<'u>
+
--- fsharp-3.1.1.26+dfsg2.orig/FSharp.PowerPack/NativeArray.fs
+++ fsharp-3.1.1.26+dfsg2/FSharp.PowerPack/NativeArray.fs
@@ -1,106 +1,106 @@
-// (c) Microsoft Corporation 2005-2009.
-
-namespace Microsoft.FSharp.NativeInterop
-
-#nowarn "44"
-#nowarn "9" // unverifiable constructs
-#nowarn "51" // The address-of operator may result in non-verifiable code. Its use is restricted to passing byrefs to functions that require them
-
-open System
-open System.Runtime.InteropServices
-open Microsoft.FSharp.NativeInterop
-
-module NativeOps = 
-    [<NoDynamicInvocation>]
-    let inline pinObjUnscoped (obj: obj) =  GCHandle.Alloc(obj,GCHandleType.Pinned) 
-    [<NoDynamicInvocation>]
-    let inline pinObj (obj: obj) f = 
-        let gch = pinObjUnscoped obj 
-        try f gch
-        finally
-            gch.Free()
-
-[<Sealed>]
-type NativeArray<'T when 'T : unmanaged>(ptr : nativeptr<'T>, len: int) =
-    member x.Ptr = ptr
-    [<NoDynamicInvocation>]
-    member inline x.Item 
-       with get n = NativePtr.get x.Ptr n
-       and  set n v = NativePtr.set x.Ptr n v
-    member x.Length = len
-
-[<Sealed>]
-type FortranMatrix<'T when 'T : unmanaged>(ptr : nativeptr<'T>, nrows: int, ncols:int) = 
-    member x.NumCols = ncols
-    member x.NumRows = nrows
-    member x.Ptr = ptr
-    [<NoDynamicInvocation>]
-    member inline x.Item 
-       with get (row,col) = NativePtr.get x.Ptr (row + col*x.NumRows)
-       and  set (row,col) v = NativePtr.set x.Ptr (row + col*x.NumRows) v
-    member x.NativeTranspose = new CMatrix<_>(ptr,ncols,nrows)
-  
-and 
-  [<Sealed>]
-  NativeArray2<'T when 'T : unmanaged>(ptr : nativeptr<'T>, nrows:int, ncols: int) = 
-    member x.Ptr = ptr
-    member x.NumRows = nrows
-    member x.NumCols = ncols
-    [<NoDynamicInvocation>]
-    member inline x.Item 
-       with get (row,col) = NativePtr.get x.Ptr (row*x.NumCols + col)
-       and  set (row,col) v = NativePtr.set x.Ptr (row*x.NumCols + col) v
-    member x.NativeTranspose = new FortranMatrix<_>(x.Ptr,ncols,nrows)
-  
-and CMatrix<'T when 'T : unmanaged> = NativeArray2<'T> 
-
-[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
-module Ref = 
-    [<NoDynamicInvocation>]
-    let inline pin (ref: 'T ref) (f : nativeptr<'T> -> 'b) = 
-        NativeOps.pinObj (box ref) (fun gch -> 
-            f (gch.AddrOfPinnedObject() |> NativePtr.ofNativeInt))
-
-open Microsoft.FSharp.Math
-
-[<Sealed>]
-type PinnedArray<'T when 'T : unmanaged>(narray: NativeArray<'T>, gch: GCHandle) =
-    [<NoDynamicInvocation>]
-    static member inline of_array(arr: 'T[]) =
-        let gch = NativeOps.pinObjUnscoped (box arr) 
-        let ptr = &&arr.[0]
-        new PinnedArray<'T>(new NativeArray<_>(ptr,Array.length arr),gch)
-
-    member x.Ptr = narray.Ptr
-    member x.Free() = gch.Free()
-    member x.Length = narray.Length
-    member x.NativeArray = narray
-    interface System.IDisposable with 
-        member x.Dispose() = gch.Free()
-        
-
-[<Sealed>]
-type PinnedArray2<'T when 'T : unmanaged>(narray: NativeArray2<'T>, gch: GCHandle) =
-
-    [<NoDynamicInvocation>]
-    static member inline of_array2(arr: 'T[,]) = 
-        let gch = NativeOps.pinObjUnscoped (box arr) 
-        let ptr = &&arr.[0,0]
-        new PinnedArray2<'T>(new NativeArray2<_>(ptr,Array2D.length1 arr,Array2D.length2 arr),gch)
-
-    [<NoDynamicInvocation>]
-    static member inline of_array2D(arr: 'T[,]) = 
-        let gch = NativeOps.pinObjUnscoped (box arr) 
-        let ptr = &&arr.[0,0]
-        new PinnedArray2<'T>(new NativeArray2<_>(ptr,Array2D.length1 arr,Array2D.length2 arr),gch)
-
-
-    member x.Ptr = narray.Ptr
-    member x.Free() = gch.Free()
-    member x.NumRows = narray.NumRows
-    member x.NumCols = narray.NumCols
-    member x.NativeArray = narray
-    interface System.IDisposable with 
-        member x.Dispose() = gch.Free()
-
-
+// (c) Microsoft Corporation 2005-2009.
+
+namespace Microsoft.FSharp.NativeInterop
+
+#nowarn "44"
+#nowarn "9" // unverifiable constructs
+#nowarn "51" // The address-of operator may result in non-verifiable code. Its use is restricted to passing byrefs to functions that require them
+
+open System
+open System.Runtime.InteropServices
+open Microsoft.FSharp.NativeInterop
+
+module NativeOps = 
+    [<NoDynamicInvocation>]
+    let inline pinObjUnscoped (obj: obj) =  GCHandle.Alloc(obj,GCHandleType.Pinned) 
+    [<NoDynamicInvocation>]
+    let inline pinObj (obj: obj) f = 
+        let gch = pinObjUnscoped obj 
+        try f gch
+        finally
+            gch.Free()
+
+[<Sealed>]
+type NativeArray<'T when 'T : unmanaged>(ptr : nativeptr<'T>, len: int) =
+    member x.Ptr = ptr
+    [<NoDynamicInvocation>]
+    member inline x.Item 
+       with get n = NativePtr.get x.Ptr n
+       and  set n v = NativePtr.set x.Ptr n v
+    member x.Length = len
+
+[<Sealed>]
+type FortranMatrix<'T when 'T : unmanaged>(ptr : nativeptr<'T>, nrows: int, ncols:int) = 
+    member x.NumCols = ncols
+    member x.NumRows = nrows
+    member x.Ptr = ptr
+    [<NoDynamicInvocation>]
+    member inline x.Item 
+       with get (row,col) = NativePtr.get x.Ptr (row + col*x.NumRows)
+       and  set (row,col) v = NativePtr.set x.Ptr (row + col*x.NumRows) v
+    member x.NativeTranspose = new CMatrix<_>(ptr,ncols,nrows)
+  
+and 
+  [<Sealed>]
+  NativeArray2<'T when 'T : unmanaged>(ptr : nativeptr<'T>, nrows:int, ncols: int) = 
+    member x.Ptr = ptr
+    member x.NumRows = nrows
+    member x.NumCols = ncols
+    [<NoDynamicInvocation>]
+    member inline x.Item 
+       with get (row,col) = NativePtr.get x.Ptr (row*x.NumCols + col)
+       and  set (row,col) v = NativePtr.set x.Ptr (row*x.NumCols + col) v
+    member x.NativeTranspose = new FortranMatrix<_>(x.Ptr,ncols,nrows)
+  
+and CMatrix<'T when 'T : unmanaged> = NativeArray2<'T> 
+
+[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+module Ref = 
+    [<NoDynamicInvocation>]
+    let inline pin (ref: 'T ref) (f : nativeptr<'T> -> 'b) = 
+        NativeOps.pinObj (box ref) (fun gch -> 
+            f (gch.AddrOfPinnedObject() |> NativePtr.ofNativeInt))
+
+open Microsoft.FSharp.Math
+
+[<Sealed>]
+type PinnedArray<'T when 'T : unmanaged>(narray: NativeArray<'T>, gch: GCHandle) =
+    [<NoDynamicInvocation>]
+    static member inline of_array(arr: 'T[]) =
+        let gch = NativeOps.pinObjUnscoped (box arr) 
+        let ptr = &&arr.[0]
+        new PinnedArray<'T>(new NativeArray<_>(ptr,Array.length arr),gch)
+
+    member x.Ptr = narray.Ptr
+    member x.Free() = gch.Free()
+    member x.Length = narray.Length
+    member x.NativeArray = narray
+    interface System.IDisposable with 
+        member x.Dispose() = gch.Free()
+        
+
+[<Sealed>]
+type PinnedArray2<'T when 'T : unmanaged>(narray: NativeArray2<'T>, gch: GCHandle) =
+
+    [<NoDynamicInvocation>]
+    static member inline of_array2(arr: 'T[,]) = 
+        let gch = NativeOps.pinObjUnscoped (box arr) 
+        let ptr = &&arr.[0,0]
+        new PinnedArray2<'T>(new NativeArray2<_>(ptr,Array2D.length1 arr,Array2D.length2 arr),gch)
+
+    [<NoDynamicInvocation>]
+    static member inline of_array2D(arr: 'T[,]) = 
+        let gch = NativeOps.pinObjUnscoped (box arr) 
+        let ptr = &&arr.[0,0]
+        new PinnedArray2<'T>(new NativeArray2<_>(ptr,Array2D.length1 arr,Array2D.length2 arr),gch)
+
+
+    member x.Ptr = narray.Ptr
+    member x.Free() = gch.Free()
+    member x.NumRows = narray.NumRows
+    member x.NumCols = narray.NumCols
+    member x.NativeArray = narray
+    interface System.IDisposable with 
+        member x.Dispose() = gch.Free()
+
+
--- fsharp-3.1.1.26+dfsg2.orig/FSharp.PowerPack/NativeArray.fsi
+++ fsharp-3.1.1.26+dfsg2/FSharp.PowerPack/NativeArray.fsi
@@ -1,159 +1,159 @@
-// (c) Microsoft Corporation 2005-2009. 
-
-namespace Microsoft.FSharp.NativeInterop
-
-open System.Runtime.InteropServices
-
-/// This type wraps a pointer to a blob of unmanaged memory assumed to contain
-/// a C-style one-dimensional array of items compatible with the (presumably blittable) 
-/// type 'T.  The blob of memory must be allocated and managed externally, 
-/// e.g. by a computation routine written in C.
-///
-/// All operations on this type are marked inlined
-/// because the code used to implement the operations is not verifiable.  
-///
-/// Any code that uses these operations will be unverifiable and may 
-/// cause memory corruption if not used with extreme care.
-[<Sealed>]
-type NativeArray<'T when 'T : unmanaged> =
-
-    /// Creates a C-style one dimensional array from a native pointer and the length of the array
-    /// Nothing is actually copied.
-    new : startAddress: nativeptr<'T> * length: int -> NativeArray<'T>
-
-    /// Pointer to the C-style one-dimensional array
-    member Ptr: nativeptr<'T>
-
-    /// Get or set an entry in the array
-    [<Unverifiable>]
-    [<NoDynamicInvocation>]
-    member inline Item : int -> 'T with get,set
-
-    /// Length of the C-style one-dimensional array
-    member Length : int
-
-/// This type wraps a pointer to a blob of unmanaged memory assumed to contain
-/// a C-style row major two-dimensional matrix of items compatible with the (presumably blittable) 
-/// type 'T. The blob of memory must be allocated and managed externally, 
-/// e.g. by a computation routine written in C.
-///
-/// All operations on this type are marked inlined
-/// because the code used to implement the operations is not verifiable.  
-///
-/// Any code that uses these operations will be unverifiable and may 
-/// cause memory corruption if not used with extreme care.
-
-[<Sealed>]
-type NativeArray2<'T when 'T : unmanaged> =
-    /// Creates a C-style row major two-dimensional array from a native pointer, the number of rows and the number of columns.  
-    /// Nothing is actually copied.
-    new : nativeptr<'T> * nrows:int * ncols:int -> NativeArray2<'T>
-
-    /// Pointer to the C-style row major two-dimensional array 
-    member Ptr: nativeptr<'T>
-
-    /// Get the number of rows of the native array
-    member NumRows : int
-
-    /// Get the number of columns of the native array
-    member NumCols : int
-
-    /// Get or set an entry in the array
-    [<Unverifiable>]
-    [<NoDynamicInvocation>]
-    member inline Item : int * int -> 'T with get,set
-
-    /// View a CMatrix as a FortranMatrix.  Doesn't actually allocate
-    /// a new matirx - just gives a different label to the same bits, and swaps the
-    /// row/column count information associated with the bits.
-    member NativeTranspose : FortranMatrix<'T>
-
-/// See NativeArray2
-and CMatrix<'T  when 'T : unmanaged> = NativeArray2<'T> 
-
-/// This type wraps a pointer to a blob of unmanaged memory assumed to contain
-/// a Fortran-style column major two-dimensional matrix of items compatible with the (presumably blittable) 
-/// type 'T. The blob of memory must be allocated and managed externally, 
-/// e.g. by a computation routine written in C.
-///
-/// All operations on this type are marked inlined
-/// because the code used to implement the operations is not verifiable.  
-///
-/// Any code that uses these operations will be unverifiable and may 
-/// cause memory corruption if not used with extreme care.
-and 
-   [<Sealed>]
-   FortranMatrix<'T when 'T : unmanaged> =
-    new : nativeptr<'T> * nrows:int * ncols:int -> FortranMatrix<'T>
-
-    member Ptr: nativeptr<'T>
-
-    member NumRows : int
-    member NumCols : int
-
-    /// Get or set an entry in the array
-    [<Unverifiable>]
-    [<NoDynamicInvocation>]
-    member inline Item : int * int -> 'T with get,set
-    
-    /// View a FortranMatrix as a CMatrix.  Doesn't actually allocate
-    /// a new matirx - just gives a different label to the same bits, and swaps the
-    /// row/column count information associated with the bits.
-    member NativeTranspose : CMatrix<'T>
-  
-[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
-module Ref =
-    /// Pin the given ref for the duration of a single call to the given function.  A native pointer to
-    /// the contents of the ref is passed to the given function.  Cleanup the GCHandle associated with the 
-    /// pin when the function completes, even if an exception is raised.
-    [<Unverifiable>]
-    [<NoDynamicInvocation>]
-    val inline pin : 'T ref -> (nativeptr<'T> -> 'U) -> 'U
-
-/// Represents a pinned handle to a structure with an underlying 1D array, i.e. an underlying NativeArray.
-/// Used when interfacing with native code math libraries such as LAPACK.
-[<Sealed>]
-type PinnedArray<'T  when 'T : unmanaged> =
-
-    new : NativeArray<'T> * GCHandle -> PinnedArray<'T>
-
-    interface System.IDisposable 
-    member Ptr : nativeptr<'T> 
-
-    member Length : int 
-
-    member NativeArray : NativeArray<'T>
-
-    /// For native interop. Pin the given object
-    [<NoDynamicInvocation>]
-    static member inline of_array : 'T[] -> PinnedArray<'T>
-
-    member Free : unit -> unit
-
-/// Represents a pinned handle to a structure with an underlying 2D array, i.e. an underlying NativeArray2.
-/// Used when interfacing with native code math libraries such as LAPACK.
-[<Sealed>]
-type PinnedArray2<'T when 'T : unmanaged> =
-
-    interface System.IDisposable 
-    new : NativeArray2<'T> * GCHandle -> PinnedArray2<'T> 
-
-    member Ptr : nativeptr<'T> 
-
-    member NumRows : int 
-
-    member NumCols : int 
-
-    member NativeArray : NativeArray2<'T>
-
-    /// For native interop. Pin the given object
-    [<NoDynamicInvocation>]
-    [<System.Obsolete("This method has been renamed to of_array2D")>]
-    static member inline of_array2 : 'T[,] -> PinnedArray2<'T>
-
-    /// For native interop. Pin the given object
-    [<NoDynamicInvocation>]
-    static member inline of_array2D : 'T[,] -> PinnedArray2<'T>
-
-    member Free : unit -> unit
-
+// (c) Microsoft Corporation 2005-2009. 
+
+namespace Microsoft.FSharp.NativeInterop
+
+open System.Runtime.InteropServices
+
+/// This type wraps a pointer to a blob of unmanaged memory assumed to contain
+/// a C-style one-dimensional array of items compatible with the (presumably blittable) 
+/// type 'T.  The blob of memory must be allocated and managed externally, 
+/// e.g. by a computation routine written in C.
+///
+/// All operations on this type are marked inlined
+/// because the code used to implement the operations is not verifiable.  
+///
+/// Any code that uses these operations will be unverifiable and may 
+/// cause memory corruption if not used with extreme care.
+[<Sealed>]
+type NativeArray<'T when 'T : unmanaged> =
+
+    /// Creates a C-style one dimensional array from a native pointer and the length of the array
+    /// Nothing is actually copied.
+    new : startAddress: nativeptr<'T> * length: int -> NativeArray<'T>
+
+    /// Pointer to the C-style one-dimensional array
+    member Ptr: nativeptr<'T>
+
+    /// Get or set an entry in the array
+    [<Unverifiable>]
+    [<NoDynamicInvocation>]
+    member inline Item : int -> 'T with get,set
+
+    /// Length of the C-style one-dimensional array
+    member Length : int
+
+/// This type wraps a pointer to a blob of unmanaged memory assumed to contain
+/// a C-style row major two-dimensional matrix of items compatible with the (presumably blittable) 
+/// type 'T. The blob of memory must be allocated and managed externally, 
+/// e.g. by a computation routine written in C.
+///
+/// All operations on this type are marked inlined
+/// because the code used to implement the operations is not verifiable.  
+///
+/// Any code that uses these operations will be unverifiable and may 
+/// cause memory corruption if not used with extreme care.
+
+[<Sealed>]
+type NativeArray2<'T when 'T : unmanaged> =
+    /// Creates a C-style row major two-dimensional array from a native pointer, the number of rows and the number of columns.  
+    /// Nothing is actually copied.
+    new : nativeptr<'T> * nrows:int * ncols:int -> NativeArray2<'T>
+
+    /// Pointer to the C-style row major two-dimensional array 
+    member Ptr: nativeptr<'T>
+
+    /// Get the number of rows of the native array
+    member NumRows : int
+
+    /// Get the number of columns of the native array
+    member NumCols : int
+
+    /// Get or set an entry in the array
+    [<Unverifiable>]
+    [<NoDynamicInvocation>]
+    member inline Item : int * int -> 'T with get,set
+
+    /// View a CMatrix as a FortranMatrix.  Doesn't actually allocate
+    /// a new matirx - just gives a different label to the same bits, and swaps the
+    /// row/column count information associated with the bits.
+    member NativeTranspose : FortranMatrix<'T>
+
+/// See NativeArray2
+and CMatrix<'T  when 'T : unmanaged> = NativeArray2<'T> 
+
+/// This type wraps a pointer to a blob of unmanaged memory assumed to contain
+/// a Fortran-style column major two-dimensional matrix of items compatible with the (presumably blittable) 
+/// type 'T. The blob of memory must be allocated and managed externally, 
+/// e.g. by a computation routine written in C.
+///
+/// All operations on this type are marked inlined
+/// because the code used to implement the operations is not verifiable.  
+///
+/// Any code that uses these operations will be unverifiable and may 
+/// cause memory corruption if not used with extreme care.
+and 
+   [<Sealed>]
+   FortranMatrix<'T when 'T : unmanaged> =
+    new : nativeptr<'T> * nrows:int * ncols:int -> FortranMatrix<'T>
+
+    member Ptr: nativeptr<'T>
+
+    member NumRows : int
+    member NumCols : int
+
+    /// Get or set an entry in the array
+    [<Unverifiable>]
+    [<NoDynamicInvocation>]
+    member inline Item : int * int -> 'T with get,set
+    
+    /// View a FortranMatrix as a CMatrix.  Doesn't actually allocate
+    /// a new matirx - just gives a different label to the same bits, and swaps the
+    /// row/column count information associated with the bits.
+    member NativeTranspose : CMatrix<'T>
+  
+[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+module Ref =
+    /// Pin the given ref for the duration of a single call to the given function.  A native pointer to
+    /// the contents of the ref is passed to the given function.  Cleanup the GCHandle associated with the 
+    /// pin when the function completes, even if an exception is raised.
+    [<Unverifiable>]
+    [<NoDynamicInvocation>]
+    val inline pin : 'T ref -> (nativeptr<'T> -> 'U) -> 'U
+
+/// Represents a pinned handle to a structure with an underlying 1D array, i.e. an underlying NativeArray.
+/// Used when interfacing with native code math libraries such as LAPACK.
+[<Sealed>]
+type PinnedArray<'T  when 'T : unmanaged> =
+
+    new : NativeArray<'T> * GCHandle -> PinnedArray<'T>
+
+    interface System.IDisposable 
+    member Ptr : nativeptr<'T> 
+
+    member Length : int 
+
+    member NativeArray : NativeArray<'T>
+
+    /// For native interop. Pin the given object
+    [<NoDynamicInvocation>]
+    static member inline of_array : 'T[] -> PinnedArray<'T>
+
+    member Free : unit -> unit
+
+/// Represents a pinned handle to a structure with an underlying 2D array, i.e. an underlying NativeArray2.
+/// Used when interfacing with native code math libraries such as LAPACK.
+[<Sealed>]
+type PinnedArray2<'T when 'T : unmanaged> =
+
+    interface System.IDisposable 
+    new : NativeArray2<'T> * GCHandle -> PinnedArray2<'T> 
+
+    member Ptr : nativeptr<'T> 
+
+    member NumRows : int 
+
+    member NumCols : int 
+
+    member NativeArray : NativeArray2<'T>
+
+    /// For native interop. Pin the given object
+    [<NoDynamicInvocation>]
+    [<System.Obsolete("This method has been renamed to of_array2D")>]
+    static member inline of_array2 : 'T[,] -> PinnedArray2<'T>
+
+    /// For native interop. Pin the given object
+    [<NoDynamicInvocation>]
+    static member inline of_array2D : 'T[,] -> PinnedArray2<'T>
+
+    member Free : unit -> unit
+
--- fsharp-3.1.1.26+dfsg2.orig/FSharp.PowerPack/Parsing.fs
+++ fsharp-3.1.1.26+dfsg2/FSharp.PowerPack/Parsing.fs
@@ -1,509 +1,509 @@
-// (c) Microsoft Corporation 2005-2009. 
-
-#if INTERNALIZED_POWER_PACK
-
-namespace  Internal.Utilities.Text.Parsing
-open Internal.Utilities
-open Internal.Utilities.Text.Lexing
-
-#else
-namespace Microsoft.FSharp.Text.Parsing
-open Microsoft.FSharp.Text.Lexing
-#endif
-
-
-
-open System
-open System.Collections.Generic
-
-#if INTERNALIZED_POWER_PACK
-type internal IParseState = 
-#else
-type IParseState = 
-#endif
-    abstract InputRange: int -> Position * Position
-    abstract InputEndPosition: int -> Position 
-    abstract InputStartPosition: int -> Position 
-    abstract ResultRange: Position * Position
-    abstract GetInput: int -> obj 
-    abstract ParserLocalStore : IDictionary<string,obj>
-    abstract RaiseError<'b> : unit -> 'b 
-
-//-------------------------------------------------------------------------
-// This context is passed to the error reporter when a syntax error occurs
-
-[<Sealed>]
-#if INTERNALIZED_POWER_PACK
-type internal ParseErrorContext<'tok>
-#else
-type ParseErrorContext<'tok>
-#endif
-         (//lexbuf: LexBuffer<_>,
-          stateStack:int list,
-          parseState: IParseState, 
-          reduceTokens: int list, 
-          currentToken: 'tok option, 
-          reducibleProductions: int list list, 
-          shiftableTokens: int list , 
-          message : string) =
-      //member x.LexBuffer = lexbuf
-      member x.StateStack  = stateStack
-      member x.ReduceTokens = reduceTokens
-      member x.CurrentToken = currentToken
-      member x.ParseState = parseState
-      member x.ReducibleProductions = reducibleProductions
-      member x.ShiftTokens = shiftableTokens
-      member x.Message = message
-
-
-//-------------------------------------------------------------------------
-// This is the data structure emitted as code by FSYACC.  
-
-#if INTERNALIZED_POWER_PACK
-type internal Tables<'tok> = 
-#else
-type Tables<'tok> = 
-#endif
-    { reductions: (IParseState -> obj) array;
-      endOfInputTag: int;
-      tagOfToken: 'tok -> int;
-      dataOfToken: 'tok -> obj; 
-      actionTableElements: uint16[];  
-      actionTableRowOffsets: uint16[];
-      reductionSymbolCounts: uint16[];
-      immediateActions: uint16[];
-      gotos: uint16[];
-      sparseGotoTableRowOffsets: uint16[];
-      stateToProdIdxsTableElements: uint16[];  
-      stateToProdIdxsTableRowOffsets: uint16[];  
-      productionToNonTerminalTable: uint16[];
-      /// For fsyacc.exe, this entry is filled in by context from the generated parser file. If no 'parse_error' function
-      /// is defined by the user then ParseHelpers.parse_error is used by default (ParseHelpers is opened
-      /// at the top of the generated parser file)
-      parseError:  ParseErrorContext<'tok> -> unit;
-      numTerminals: int;
-      tagOfErrorTerminal: int }
-
-//-------------------------------------------------------------------------
-// An implementation of stacks.
-
-// This type is in System.dll so for the moment we can't use it in FSharp.Core.dll
-//type Stack<'a> = System.Collections.Generic.Stack<'a>
-
-#if INTERNALIZED_POWER_PACK
-type Stack<'a>(n)  = 
-#else
-type internal Stack<'a>(n)  = 
-#endif
-    let mutable contents = Array.zeroCreate<'a>(n)
-    let mutable count = 0
-
-    member buf.Ensure newSize = 
-        let oldSize = Array.length contents
-        if newSize > oldSize then 
-            let old = contents
-            contents <- Array.zeroCreate (max newSize (oldSize * 2));
-            Array.blit old 0 contents 0 count;
-    
-    member buf.Count = count
-    member buf.Pop() = count <- count - 1
-    member buf.Peep() = contents.[count - 1]
-    member buf.Top(n) = [ for x in contents.[max 0 (count-n)..count - 1] -> x ] |> List.rev
-    member buf.Push(x) =
-        buf.Ensure(count + 1); 
-        contents.[count] <- x; 
-        count <- count + 1
-        
-    member buf.IsEmpty = (count = 0)
-    member buf.PrintStack() = 
-        for i = 0 to (count - 1) do 
-            System.Console.Write("{0}{1}",(contents.[i]),if i=count-1 then ":" else "-") 
-          
-exception RecoverableParseError
-exception Accept of obj
-
-#if DEBUG
-module Flags = 
-    let mutable debug = false
-#endif
-
-#if INTERNALIZED_POWER_PACK
-module internal Implementation = 
-#else
-module Implementation = 
-#endif
-    
-    // Definitions shared with fsyacc 
-    let anyMarker = 0xffff
-    let shiftFlag = 0x0000
-    let reduceFlag = 0x4000
-    let errorFlag = 0x8000
-    let acceptFlag = 0xc000
-    let actionMask = 0xc000
-
-    let actionValue action = action &&& (~~~ actionMask)                                    
-    let actionKind action = action &&& actionMask
-    
-    //-------------------------------------------------------------------------
-    // Read the tables written by FSYACC.  
-
-    type AssocTable(elemTab:uint16[], offsetTab:uint16[]) =
-        let cache = new Dictionary<_,_>(2000)
-
-        member t.readAssoc (minElemNum,maxElemNum,defaultValueOfAssoc,keyToFind) =     
-            // do a binary chop on the table 
-            let elemNumber : int = (minElemNum+maxElemNum)/2
-            if elemNumber = maxElemNum 
-            then defaultValueOfAssoc
-            else 
-                let x = int elemTab.[elemNumber*2]
-                if keyToFind = x then 
-                    int elemTab.[elemNumber*2+1]
-                elif keyToFind < x then t.readAssoc (minElemNum ,elemNumber,defaultValueOfAssoc,keyToFind)
-                else                    t.readAssoc (elemNumber+1,maxElemNum,defaultValueOfAssoc,keyToFind)
-
-        member t.Read(rowNumber ,keyToFind) =
-        
-            // First check the sparse lookaside table
-            // Performance note: without this lookaside table the binary chop in readAssoc
-            // takes up around 10% of of parsing time 
-            // for parsing intensive samples such as the bootstrapped F# compiler.
-            //
-            // Note: using a .NET Dictionary for this int -> int table looks like it could be sub-optimal.
-            // Some other better sparse lookup table may be better.
-            let mutable res = 0 
-            let cacheKey = (rowNumber <<< 16) ||| keyToFind
-            let ok = cache.TryGetValue(cacheKey, &res) 
-            if ok then res 
-            else
-                let headOfTable = int offsetTab.[rowNumber]
-                let firstElemNumber = headOfTable + 1           
-                let numberOfElementsInAssoc = int elemTab.[headOfTable*2]
-                let defaultValueOfAssoc = int elemTab.[headOfTable*2+1]          
-                let res = t.readAssoc (firstElemNumber,(firstElemNumber+numberOfElementsInAssoc),defaultValueOfAssoc,keyToFind)
-                cache.[cacheKey] <- res
-                res
-
-        // Read all entries in the association table
-        // Used during error recovery to find all valid entries in the table
-        member x.ReadAll(n) =       
-            let headOfTable = int offsetTab.[n]
-            let firstElemNumber = headOfTable + 1           
-            let numberOfElementsInAssoc = int32 elemTab.[headOfTable*2]           
-            let defaultValueOfAssoc = int elemTab.[headOfTable*2+1]          
-            [ for i in firstElemNumber .. (firstElemNumber+numberOfElementsInAssoc-1) -> 
-                (int elemTab.[i*2], int elemTab.[i*2+1]) ], defaultValueOfAssoc
-
-    type IdxToIdxListTable(elemTab:uint16[], offsetTab:uint16[]) =
-
-        // Read all entries in a row of the table
-        member x.ReadAll(n) =       
-            let headOfTable = int offsetTab.[n]
-            let firstElemNumber = headOfTable + 1           
-            let numberOfElements = int32 elemTab.[headOfTable]           
-            [ for i in firstElemNumber .. (firstElemNumber+numberOfElements-1) -> int elemTab.[i] ]
-
-    //-------------------------------------------------------------------------
-    // interpret the tables emitted by FSYACC.  
-
-    [<NoEquality; NoComparison>]
-    [<Struct>]
-    type ValueInfo = 
-        val value: obj
-        val startPos: Position
-        val endPos: Position
-        new(value,startPos,endPos) = { value=value; startPos=startPos;endPos=endPos }
-
-    let interpret (tables: Tables<'tok>) lexer (lexbuf : LexBuffer<_>) initialState =                                                                      
-        let localStore = new Dictionary<string,obj>() in
-        localStore.["LexBuffer"] <- lexbuf;
-#if DEBUG
-        if Flags.debug then System.Console.WriteLine("\nParser: interpret tables");
-#endif
-        let stateStack : Stack<int> = new Stack<_>(100)
-        stateStack.Push(initialState);
-        let valueStack = new Stack<ValueInfo>(100)
-        let mutable haveLookahead = false                                                                              
-        let mutable lookaheadToken = Unchecked.defaultof<'tok>
-        let mutable lookaheadEndPos = Unchecked.defaultof<Position>
-        let mutable lookaheadStartPos = Unchecked.defaultof<Position>
-        let mutable finished = false
-        // After an error occurs, we suppress errors until we've shifted three tokens in a row.
-        let mutable errorSuppressionCountDown = 0
-        
-        // When we hit the end-of-file we don't fail straight away but rather keep permitting shift
-        // and reduce against the last token in the token stream 20 times or until we've accepted
-        // or exhausted the stack. This allows error recovery rules of the form
-        //      input : realInput EOF | realInput error EOF | error EOF
-        // where consuming one EOF to trigger an error doesn't result in overall parse failure 
-        // catastrophe and the loss of intermediate results.
-        //
-        let mutable inEofCountDown = false
-        let mutable eofCountDown = 20 // Number of EOFs to supply at the end for error recovery
-        // The 100 here means a maximum of 100 elements for each rule
-        let ruleStartPoss = (Array.zeroCreate 100 : Position array)              
-        let ruleEndPoss   = (Array.zeroCreate 100 : Position array)              
-        let ruleValues    = (Array.zeroCreate 100 : obj array)              
-        let lhsPos        = (Array.zeroCreate 2 : Position array)                                            
-        let reductions = tables.reductions
-        let actionTable = new AssocTable(tables.actionTableElements, tables.actionTableRowOffsets)
-        let gotoTable = new AssocTable(tables.gotos, tables.sparseGotoTableRowOffsets)
-        let stateToProdIdxsTable = new IdxToIdxListTable(tables.stateToProdIdxsTableElements, tables.stateToProdIdxsTableRowOffsets)
-
-        let parseState =                                                                                            
-            { new IParseState with 
-                member p.InputRange(n) = ruleStartPoss.[n-1], ruleEndPoss.[n-1]; 
-                member p.InputStartPosition(n) = ruleStartPoss.[n-1]
-                member p.InputEndPosition(n) = ruleEndPoss.[n-1]; 
-                member p.GetInput(n)    = ruleValues.[n-1];        
-                member p.ResultRange    = (lhsPos.[0], lhsPos.[1]);  
-                member p.ParserLocalStore = (localStore :> IDictionary<_,_>); 
-                member p.RaiseError()  = raise RecoverableParseError  (* NOTE: this binding tests the fairly complex logic associated with an object expression implementing a generic abstract method *)
-            }       
-
-#if DEBUG
-        let report haveLookahead lookaheadToken = 
-            if haveLookahead then sprintf "%A" lookaheadToken 
-            else "[TBC]"
-#endif
-
-        // Pop the stack until we can shift the 'error' token. If 'tokenOpt' is given
-        // then keep popping until we can shift both the 'error' token and the token in 'tokenOpt'.
-        // This is used at end-of-file to make sure we can shift both the 'error' token and the 'EOF' token.
-        let rec popStackUntilErrorShifted(tokenOpt) =
-            // Keep popping the stack until the "error" terminal is shifted
-#if DEBUG
-            if Flags.debug then System.Console.WriteLine("popStackUntilErrorShifted");
-#endif
-            if stateStack.IsEmpty then 
-#if DEBUG
-                if Flags.debug then 
-                    System.Console.WriteLine("state stack empty during error recovery - generating parse error");
-#endif
-                failwith "parse error";
-            
-            let currState = stateStack.Peep()
-#if DEBUG
-            if Flags.debug then 
-                System.Console.WriteLine("In state {0} during error recovery", currState);
-#endif
-            
-            let action = actionTable.Read(currState, tables.tagOfErrorTerminal)
-            
-            if actionKind action = shiftFlag &&  
-                (match tokenOpt with 
-                 | None -> true
-                 | Some(token) -> 
-                    let nextState = actionValue action 
-                    actionKind (actionTable.Read(nextState, tables.tagOfToken(token))) = shiftFlag) then
-
-#if DEBUG
-                if Flags.debug then System.Console.WriteLine("shifting error, continuing with error recovery");
-#endif
-                let nextState = actionValue action 
-                // The "error" non terminal needs position information, though it tends to be unreliable.
-                // Use the StartPos/EndPos from the lex buffer
-                valueStack.Push(ValueInfo(box (), lexbuf.StartPos, lexbuf.EndPos));
-                stateStack.Push(nextState)
-            else
-                if valueStack.IsEmpty then 
-                    failwith "parse error";
-#if DEBUG
-                if Flags.debug then 
-                    System.Console.WriteLine("popping stack during error recovery");
-#endif
-                valueStack.Pop();
-                stateStack.Pop();
-                popStackUntilErrorShifted(tokenOpt)
-
-        while not finished do                                                                                    
-            if stateStack.IsEmpty then 
-                finished <- true
-            else
-                let state = stateStack.Peep()
-#if DEBUG
-                if Flags.debug then (Console.Write("{0} value(state), state ",valueStack.Count); stateStack.PrintStack())
-#endif
-                let action = 
-                    let immediateAction = int tables.immediateActions.[state]
-                    if not (immediateAction = anyMarker) then
-                        // Action has been pre-determined, no need to lookahead 
-                        // Expecting it to be a Reduce action on a non-fakeStartNonTerminal ? 
-                        immediateAction
-                    else
-                        // Lookahead required to determine action 
-                        if not haveLookahead then 
-                            if lexbuf.IsPastEndOfStream then 
-                                // When the input runs out, keep supplying the last token for eofCountDown times
-                                if eofCountDown>0 then
-                                    haveLookahead <- true
-                                    eofCountDown <- eofCountDown - 1
-                                    inEofCountDown <- true
-                                else 
-                                    haveLookahead <- false
-                            else 
-                                lookaheadToken <- lexer lexbuf
-                                lookaheadStartPos <- lexbuf.StartPos
-                                lookaheadEndPos <- lexbuf.EndPos
-                                haveLookahead <- true;
-
-                        let tag = 
-                            if haveLookahead then tables.tagOfToken lookaheadToken 
-                            else tables.endOfInputTag   
-                                    
-                        // Printf.printf "state %d\n" state  
-                        actionTable.Read(state,tag)
-                        
-                let kind = actionKind action 
-                if kind = shiftFlag then (
-                    if errorSuppressionCountDown > 0 then 
-                        errorSuppressionCountDown <- errorSuppressionCountDown - 1;
-#if DEBUG
-                        if Flags.debug then Console.WriteLine("shifting, reduced errorRecoverylevel to {0}\n", errorSuppressionCountDown);
-#endif
-                    let nextState = actionValue action                                     
-                    if not haveLookahead then failwith "shift on end of input!";
-                    let data = tables.dataOfToken lookaheadToken
-                    valueStack.Push(ValueInfo(data, lookaheadStartPos, lookaheadEndPos));
-                    stateStack.Push(nextState);                                                                
-#if DEBUG
-                    if Flags.debug then Console.WriteLine("shift/consume input {0}, shift to state {1}", report haveLookahead lookaheadToken, nextState);
-#endif
-                    haveLookahead <- false
-
-                ) elif kind = reduceFlag then
-                    let prod = actionValue action                                     
-                    let reduction = reductions.[prod]                                                             
-                    let n = int tables.reductionSymbolCounts.[prod]
-                       // pop the symbols, populate the values and populate the locations                              
-#if DEBUG
-                    if Flags.debug then Console.Write("reduce popping {0} values/states, lookahead {1}", n, report haveLookahead lookaheadToken);
-#endif
-                    
-                    lhsPos.[0] <- Position.Empty;                                                                     
-                    lhsPos.[1] <- Position.Empty;  
-                    for i = 0 to n - 1 do                                                                             
-                        if valueStack.IsEmpty then failwith "empty symbol stack";
-                        let topVal = valueStack.Peep()
-                        valueStack.Pop();
-                        stateStack.Pop();
-                        ruleValues.[(n-i)-1] <- topVal.value;  
-                        ruleStartPoss.[(n-i)-1] <- topVal.startPos;  
-                        ruleEndPoss.[(n-i)-1] <- topVal.endPos;  
-                        if lhsPos.[1] = Position.Empty then lhsPos.[1] <- topVal.endPos;
-                        if not (topVal.startPos = Position.Empty) then lhsPos.[0] <- topVal.startPos
-                    done;                                                                                           
-                    
-                    try                                                                                               
-                          // Printf.printf "reduce %d\n" prod;                                                       
-                        let redResult = reduction parseState                                                          
-                        valueStack.Push(ValueInfo(redResult, lhsPos.[0], lhsPos.[1]));
-                        let currState = stateStack.Peep()
-                        let newGotoState = gotoTable.Read(int tables.productionToNonTerminalTable.[prod], currState)
-                        stateStack.Push(newGotoState)
-#if DEBUG
-                        if Flags.debug then Console.WriteLine(" goto state {0}", newGotoState)
-#endif
-                    with                                                                                              
-                    | Accept res ->                                                                            
-                          finished <- true;                                                                             
-                          valueStack.Push(ValueInfo(res, lhsPos.[0], lhsPos.[1])) 
-                    | RecoverableParseError ->
-#if DEBUG
-                          if Flags.debug then Console.WriteLine("RecoverableParseErrorException...\n");
-#endif
-                          popStackUntilErrorShifted(None);
-                          // User code raised a Parse_error. Don't report errors again until three tokens have been shifted 
-                          errorSuppressionCountDown <- 3
-                elif kind = errorFlag then (
-#if DEBUG
-                    if Flags.debug then Console.Write("ErrorFlag... ");
-#endif
-                    // Silently discard inputs and don't report errors 
-                    // until three tokens in a row have been shifted 
-#if DEBUG
-                    if Flags.debug then printfn "error on token '%A' " (if haveLookahead then Some(lookaheadToken) else None);
-#endif
-                    if errorSuppressionCountDown > 0 then 
-                        // If we're in the end-of-file count down then we're very keen to 'Accept'.
-                        // We can only do this by repeatedly popping the stack until we can shift both an 'error' token
-                        // and an EOF token. 
-                        if inEofCountDown && eofCountDown < 10 then 
-#if DEBUG
-                            if Flags.debug then printfn "poppin stack, lokking to shift both 'error' and that token, during end-of-file error recovery" ;
-#endif
-                            popStackUntilErrorShifted(if haveLookahead then Some(lookaheadToken) else None);
-
-                        // If we don't haveLookahead then the end-of-file count down is over and we have no further options.
-                        if not haveLookahead then 
-                            failwith "parse error: unexpected end of file"
-                            
-#if DEBUG
-                        if Flags.debug then printfn "discarding token '%A' during error suppression" (if haveLookahead then Some(lookaheadToken) else None);
-#endif
-                        // Discard the token
-                        haveLookahead <- false
-                        // Try again to shift three tokens
-                        errorSuppressionCountDown <- 3
-                    else (
-
-                        let currentToken = if haveLookahead then Some(lookaheadToken) else None
-                        let actions,defaultAction = actionTable.ReadAll(state) 
-                        let explicit = Set.ofList [ for (tag,_action) in actions -> tag ]
-                        
-                        let shiftableTokens = 
-                           [ for (tag,action) in actions do
-                                 if (actionKind action) = shiftFlag then 
-                                     yield tag
-                             if actionKind defaultAction = shiftFlag  then
-                                 for tag in 0 .. tables.numTerminals-1 do  
-                                    if not (explicit.Contains(tag)) then 
-                                         yield tag ] in
-
-                        let stateStack = stateStack.Top(12) in
-                        let reducibleProductions = 
-                            [ for state in stateStack do 
-                               yield stateToProdIdxsTable.ReadAll(state)  ]
-
-                        let reduceTokens = 
-                           [ for (tag,action) in actions do
-                                if actionKind(action) = reduceFlag then
-                                    yield tag
-                             if actionKind(defaultAction) = reduceFlag  then
-                                 for tag in 0 .. tables.numTerminals-1 do  
-                                    if not (explicit.Contains(tag)) then 
-                                         yield tag ] in
-                        //let activeRules = stateStack |> List.iter (fun state -> 
-                        let errorContext = new ParseErrorContext<'tok>(stateStack,parseState, reduceTokens,currentToken,reducibleProductions, shiftableTokens, "syntax error")
-                        tables.parseError(errorContext);
-                        popStackUntilErrorShifted(None);
-                        errorSuppressionCountDown <- 3;
-#if DEBUG
-                        if Flags.debug then System.Console.WriteLine("generated syntax error and shifted error token, haveLookahead = {0}\n", haveLookahead);
-#endif
-                    )
-                ) elif kind = acceptFlag then 
-                    finished <- true
-#if DEBUG
-                else
-                  if Flags.debug then System.Console.WriteLine("ALARM!!! drop through case in parser");  
-#endif
-        done;                                                                                                     
-        // OK, we're done - read off the overall generated value
-        valueStack.Peep().value
-
-#if INTERNALIZED_POWER_PACK
-type internal Tables<'tok> with
-#else
-type Tables<'tok> with
-#endif
-    member tables.Interpret (lexer,lexbuf,initialState) = 
-        Implementation.interpret tables lexer lexbuf initialState
-    
-#if INTERNALIZED_POWER_PACK
-module internal ParseHelpers = 
-#else
-module ParseHelpers = 
-#endif
-    let parse_error (_s:string) = ()
-    let parse_error_rich = (None : (ParseErrorContext<_> -> unit) option)
+// (c) Microsoft Corporation 2005-2009. 
+
+#if INTERNALIZED_POWER_PACK
+
+namespace  Internal.Utilities.Text.Parsing
+open Internal.Utilities
+open Internal.Utilities.Text.Lexing
+
+#else
+namespace Microsoft.FSharp.Text.Parsing
+open Microsoft.FSharp.Text.Lexing
+#endif
+
+
+
+open System
+open System.Collections.Generic
+
+#if INTERNALIZED_POWER_PACK
+type internal IParseState = 
+#else
+type IParseState = 
+#endif
+    abstract InputRange: int -> Position * Position
+    abstract InputEndPosition: int -> Position 
+    abstract InputStartPosition: int -> Position 
+    abstract ResultRange: Position * Position
+    abstract GetInput: int -> obj 
+    abstract ParserLocalStore : IDictionary<string,obj>
+    abstract RaiseError<'b> : unit -> 'b 
+
+//-------------------------------------------------------------------------
+// This context is passed to the error reporter when a syntax error occurs
+
+[<Sealed>]
+#if INTERNALIZED_POWER_PACK
+type internal ParseErrorContext<'tok>
+#else
+type ParseErrorContext<'tok>
+#endif
+         (//lexbuf: LexBuffer<_>,
+          stateStack:int list,
+          parseState: IParseState, 
+          reduceTokens: int list, 
+          currentToken: 'tok option, 
+          reducibleProductions: int list list, 
+          shiftableTokens: int list , 
+          message : string) =
+      //member x.LexBuffer = lexbuf
+      member x.StateStack  = stateStack
+      member x.ReduceTokens = reduceTokens
+      member x.CurrentToken = currentToken
+      member x.ParseState = parseState
+      member x.ReducibleProductions = reducibleProductions
+      member x.ShiftTokens = shiftableTokens
+      member x.Message = message
+
+
+//-------------------------------------------------------------------------
+// This is the data structure emitted as code by FSYACC.  
+
+#if INTERNALIZED_POWER_PACK
+type internal Tables<'tok> = 
+#else
+type Tables<'tok> = 
+#endif
+    { reductions: (IParseState -> obj) array;
+      endOfInputTag: int;
+      tagOfToken: 'tok -> int;
+      dataOfToken: 'tok -> obj; 
+      actionTableElements: uint16[];  
+      actionTableRowOffsets: uint16[];
+      reductionSymbolCounts: uint16[];
+      immediateActions: uint16[];
+      gotos: uint16[];
+      sparseGotoTableRowOffsets: uint16[];
+      stateToProdIdxsTableElements: uint16[];  
+      stateToProdIdxsTableRowOffsets: uint16[];  
+      productionToNonTerminalTable: uint16[];
+      /// For fsyacc.exe, this entry is filled in by context from the generated parser file. If no 'parse_error' function
+      /// is defined by the user then ParseHelpers.parse_error is used by default (ParseHelpers is opened
+      /// at the top of the generated parser file)
+      parseError:  ParseErrorContext<'tok> -> unit;
+      numTerminals: int;
+      tagOfErrorTerminal: int }
+
+//-------------------------------------------------------------------------
+// An implementation of stacks.
+
+// This type is in System.dll so for the moment we can't use it in FSharp.Core.dll
+//type Stack<'a> = System.Collections.Generic.Stack<'a>
+
+#if INTERNALIZED_POWER_PACK
+type Stack<'a>(n)  = 
+#else
+type internal Stack<'a>(n)  = 
+#endif
+    let mutable contents = Array.zeroCreate<'a>(n)
+    let mutable count = 0
+
+    member buf.Ensure newSize = 
+        let oldSize = Array.length contents
+        if newSize > oldSize then 
+            let old = contents
+            contents <- Array.zeroCreate (max newSize (oldSize * 2));
+            Array.blit old 0 contents 0 count;
+    
+    member buf.Count = count
+    member buf.Pop() = count <- count - 1
+    member buf.Peep() = contents.[count - 1]
+    member buf.Top(n) = [ for x in contents.[max 0 (count-n)..count - 1] -> x ] |> List.rev
+    member buf.Push(x) =
+        buf.Ensure(count + 1); 
+        contents.[count] <- x; 
+        count <- count + 1
+        
+    member buf.IsEmpty = (count = 0)
+    member buf.PrintStack() = 
+        for i = 0 to (count - 1) do 
+            System.Console.Write("{0}{1}",(contents.[i]),if i=count-1 then ":" else "-") 
+          
+exception RecoverableParseError
+exception Accept of obj
+
+#if DEBUG
+module Flags = 
+    let mutable debug = false
+#endif
+
+#if INTERNALIZED_POWER_PACK
+module internal Implementation = 
+#else
+module Implementation = 
+#endif
+    
+    // Definitions shared with fsyacc 
+    let anyMarker = 0xffff
+    let shiftFlag = 0x0000
+    let reduceFlag = 0x4000
+    let errorFlag = 0x8000
+    let acceptFlag = 0xc000
+    let actionMask = 0xc000
+
+    let actionValue action = action &&& (~~~ actionMask)                                    
+    let actionKind action = action &&& actionMask
+    
+    //-------------------------------------------------------------------------
+    // Read the tables written by FSYACC.  
+
+    type AssocTable(elemTab:uint16[], offsetTab:uint16[]) =
+        let cache = new Dictionary<_,_>(2000)
+
+        member t.readAssoc (minElemNum,maxElemNum,defaultValueOfAssoc,keyToFind) =     
+            // do a binary chop on the table 
+            let elemNumber : int = (minElemNum+maxElemNum)/2
+            if elemNumber = maxElemNum 
+            then defaultValueOfAssoc
+            else 
+                let x = int elemTab.[elemNumber*2]
+                if keyToFind = x then 
+                    int elemTab.[elemNumber*2+1]
+                elif keyToFind < x then t.readAssoc (minElemNum ,elemNumber,defaultValueOfAssoc,keyToFind)
+                else                    t.readAssoc (elemNumber+1,maxElemNum,defaultValueOfAssoc,keyToFind)
+
+        member t.Read(rowNumber ,keyToFind) =
+        
+            // First check the sparse lookaside table
+            // Performance note: without this lookaside table the binary chop in readAssoc
+            // takes up around 10% of of parsing time 
+            // for parsing intensive samples such as the bootstrapped F# compiler.
+            //
+            // Note: using a .NET Dictionary for this int -> int table looks like it could be sub-optimal.
+            // Some other better sparse lookup table may be better.
+            let mutable res = 0 
+            let cacheKey = (rowNumber <<< 16) ||| keyToFind
+            let ok = cache.TryGetValue(cacheKey, &res) 
+            if ok then res 
+            else
+                let headOfTable = int offsetTab.[rowNumber]
+                let firstElemNumber = headOfTable + 1           
+                let numberOfElementsInAssoc = int elemTab.[headOfTable*2]
+                let defaultValueOfAssoc = int elemTab.[headOfTable*2+1]          
+                let res = t.readAssoc (firstElemNumber,(firstElemNumber+numberOfElementsInAssoc),defaultValueOfAssoc,keyToFind)
+                cache.[cacheKey] <- res
+                res
+
+        // Read all entries in the association table
+        // Used during error recovery to find all valid entries in the table
+        member x.ReadAll(n) =       
+            let headOfTable = int offsetTab.[n]
+            let firstElemNumber = headOfTable + 1           
+            let numberOfElementsInAssoc = int32 elemTab.[headOfTable*2]           
+            let defaultValueOfAssoc = int elemTab.[headOfTable*2+1]          
+            [ for i in firstElemNumber .. (firstElemNumber+numberOfElementsInAssoc-1) -> 
+                (int elemTab.[i*2], int elemTab.[i*2+1]) ], defaultValueOfAssoc
+
+    type IdxToIdxListTable(elemTab:uint16[], offsetTab:uint16[]) =
+
+        // Read all entries in a row of the table
+        member x.ReadAll(n) =       
+            let headOfTable = int offsetTab.[n]
+            let firstElemNumber = headOfTable + 1           
+            let numberOfElements = int32 elemTab.[headOfTable]           
+            [ for i in firstElemNumber .. (firstElemNumber+numberOfElements-1) -> int elemTab.[i] ]
+
+    //-------------------------------------------------------------------------
+    // interpret the tables emitted by FSYACC.  
+
+    [<NoEquality; NoComparison>]
+    [<Struct>]
+    type ValueInfo = 
+        val value: obj
+        val startPos: Position
+        val endPos: Position
+        new(value,startPos,endPos) = { value=value; startPos=startPos;endPos=endPos }
+
+    let interpret (tables: Tables<'tok>) lexer (lexbuf : LexBuffer<_>) initialState =                                                                      
+        let localStore = new Dictionary<string,obj>() in
+        localStore.["LexBuffer"] <- lexbuf;
+#if DEBUG
+        if Flags.debug then System.Console.WriteLine("\nParser: interpret tables");
+#endif
+        let stateStack : Stack<int> = new Stack<_>(100)
+        stateStack.Push(initialState);
+        let valueStack = new Stack<ValueInfo>(100)
+        let mutable haveLookahead = false                                                                              
+        let mutable lookaheadToken = Unchecked.defaultof<'tok>
+        let mutable lookaheadEndPos = Unchecked.defaultof<Position>
+        let mutable lookaheadStartPos = Unchecked.defaultof<Position>
+        let mutable finished = false
+        // After an error occurs, we suppress errors until we've shifted three tokens in a row.
+        let mutable errorSuppressionCountDown = 0
+        
+        // When we hit the end-of-file we don't fail straight away but rather keep permitting shift
+        // and reduce against the last token in the token stream 20 times or until we've accepted
+        // or exhausted the stack. This allows error recovery rules of the form
+        //      input : realInput EOF | realInput error EOF | error EOF
+        // where consuming one EOF to trigger an error doesn't result in overall parse failure 
+        // catastrophe and the loss of intermediate results.
+        //
+        let mutable inEofCountDown = false
+        let mutable eofCountDown = 20 // Number of EOFs to supply at the end for error recovery
+        // The 100 here means a maximum of 100 elements for each rule
+        let ruleStartPoss = (Array.zeroCreate 100 : Position array)              
+        let ruleEndPoss   = (Array.zeroCreate 100 : Position array)              
+        let ruleValues    = (Array.zeroCreate 100 : obj array)              
+        let lhsPos        = (Array.zeroCreate 2 : Position array)                                            
+        let reductions = tables.reductions
+        let actionTable = new AssocTable(tables.actionTableElements, tables.actionTableRowOffsets)
+        let gotoTable = new AssocTable(tables.gotos, tables.sparseGotoTableRowOffsets)
+        let stateToProdIdxsTable = new IdxToIdxListTable(tables.stateToProdIdxsTableElements, tables.stateToProdIdxsTableRowOffsets)
+
+        let parseState =                                                                                            
+            { new IParseState with 
+                member p.InputRange(n) = ruleStartPoss.[n-1], ruleEndPoss.[n-1]; 
+                member p.InputStartPosition(n) = ruleStartPoss.[n-1]
+                member p.InputEndPosition(n) = ruleEndPoss.[n-1]; 
+                member p.GetInput(n)    = ruleValues.[n-1];        
+                member p.ResultRange    = (lhsPos.[0], lhsPos.[1]);  
+                member p.ParserLocalStore = (localStore :> IDictionary<_,_>); 
+                member p.RaiseError()  = raise RecoverableParseError  (* NOTE: this binding tests the fairly complex logic associated with an object expression implementing a generic abstract method *)
+            }       
+
+#if DEBUG
+        let report haveLookahead lookaheadToken = 
+            if haveLookahead then sprintf "%A" lookaheadToken 
+            else "[TBC]"
+#endif
+
+        // Pop the stack until we can shift the 'error' token. If 'tokenOpt' is given
+        // then keep popping until we can shift both the 'error' token and the token in 'tokenOpt'.
+        // This is used at end-of-file to make sure we can shift both the 'error' token and the 'EOF' token.
+        let rec popStackUntilErrorShifted(tokenOpt) =
+            // Keep popping the stack until the "error" terminal is shifted
+#if DEBUG
+            if Flags.debug then System.Console.WriteLine("popStackUntilErrorShifted");
+#endif
+            if stateStack.IsEmpty then 
+#if DEBUG
+                if Flags.debug then 
+                    System.Console.WriteLine("state stack empty during error recovery - generating parse error");
+#endif
+                failwith "parse error";
+            
+            let currState = stateStack.Peep()
+#if DEBUG
+            if Flags.debug then 
+                System.Console.WriteLine("In state {0} during error recovery", currState);
+#endif
+            
+            let action = actionTable.Read(currState, tables.tagOfErrorTerminal)
+            
+            if actionKind action = shiftFlag &&  
+                (match tokenOpt with 
+                 | None -> true
+                 | Some(token) -> 
+                    let nextState = actionValue action 
+                    actionKind (actionTable.Read(nextState, tables.tagOfToken(token))) = shiftFlag) then
+
+#if DEBUG
+                if Flags.debug then System.Console.WriteLine("shifting error, continuing with error recovery");
+#endif
+                let nextState = actionValue action 
+                // The "error" non terminal needs position information, though it tends to be unreliable.
+                // Use the StartPos/EndPos from the lex buffer
+                valueStack.Push(ValueInfo(box (), lexbuf.StartPos, lexbuf.EndPos));
+                stateStack.Push(nextState)
+            else
+                if valueStack.IsEmpty then 
+                    failwith "parse error";
+#if DEBUG
+                if Flags.debug then 
+                    System.Console.WriteLine("popping stack during error recovery");
+#endif
+                valueStack.Pop();
+                stateStack.Pop();
+                popStackUntilErrorShifted(tokenOpt)
+
+        while not finished do                                                                                    
+            if stateStack.IsEmpty then 
+                finished <- true
+            else
+                let state = stateStack.Peep()
+#if DEBUG
+                if Flags.debug then (Console.Write("{0} value(state), state ",valueStack.Count); stateStack.PrintStack())
+#endif
+                let action = 
+                    let immediateAction = int tables.immediateActions.[state]
+                    if not (immediateAction = anyMarker) then
+                        // Action has been pre-determined, no need to lookahead 
+                        // Expecting it to be a Reduce action on a non-fakeStartNonTerminal ? 
+                        immediateAction
+                    else
+                        // Lookahead required to determine action 
+                        if not haveLookahead then 
+                            if lexbuf.IsPastEndOfStream then 
+                                // When the input runs out, keep supplying the last token for eofCountDown times
+                                if eofCountDown>0 then
+                                    haveLookahead <- true
+                                    eofCountDown <- eofCountDown - 1
+                                    inEofCountDown <- true
+                                else 
+                                    haveLookahead <- false
+                            else 
+                                lookaheadToken <- lexer lexbuf
+                                lookaheadStartPos <- lexbuf.StartPos
+                                lookaheadEndPos <- lexbuf.EndPos
+                                haveLookahead <- true;
+
+                        let tag = 
+                            if haveLookahead then tables.tagOfToken lookaheadToken 
+                            else tables.endOfInputTag   
+                                    
+                        // Printf.printf "state %d\n" state  
+                        actionTable.Read(state,tag)
+                        
+                let kind = actionKind action 
+                if kind = shiftFlag then (
+                    if errorSuppressionCountDown > 0 then 
+                        errorSuppressionCountDown <- errorSuppressionCountDown - 1;
+#if DEBUG
+                        if Flags.debug then Console.WriteLine("shifting, reduced errorRecoverylevel to {0}\n", errorSuppressionCountDown);
+#endif
+                    let nextState = actionValue action                                     
+                    if not haveLookahead then failwith "shift on end of input!";
+                    let data = tables.dataOfToken lookaheadToken
+                    valueStack.Push(ValueInfo(data, lookaheadStartPos, lookaheadEndPos));
+                    stateStack.Push(nextState);                                                                
+#if DEBUG
+                    if Flags.debug then Console.WriteLine("shift/consume input {0}, shift to state {1}", report haveLookahead lookaheadToken, nextState);
+#endif
+                    haveLookahead <- false
+
+                ) elif kind = reduceFlag then
+                    let prod = actionValue action                                     
+                    let reduction = reductions.[prod]                                                             
+                    let n = int tables.reductionSymbolCounts.[prod]
+                       // pop the symbols, populate the values and populate the locations                              
+#if DEBUG
+                    if Flags.debug then Console.Write("reduce popping {0} values/states, lookahead {1}", n, report haveLookahead lookaheadToken);
+#endif
+                    
+                    lhsPos.[0] <- Position.Empty;                                                                     
+                    lhsPos.[1] <- Position.Empty;  
+                    for i = 0 to n - 1 do                                                                             
+                        if valueStack.IsEmpty then failwith "empty symbol stack";
+                        let topVal = valueStack.Peep()
+                        valueStack.Pop();
+                        stateStack.Pop();
+                        ruleValues.[(n-i)-1] <- topVal.value;  
+                        ruleStartPoss.[(n-i)-1] <- topVal.startPos;  
+                        ruleEndPoss.[(n-i)-1] <- topVal.endPos;  
+                        if lhsPos.[1] = Position.Empty then lhsPos.[1] <- topVal.endPos;
+                        if not (topVal.startPos = Position.Empty) then lhsPos.[0] <- topVal.startPos
+                    done;                                                                                           
+                    
+                    try                                                                                               
+                          // Printf.printf "reduce %d\n" prod;                                                       
+                        let redResult = reduction parseState                                                          
+                        valueStack.Push(ValueInfo(redResult, lhsPos.[0], lhsPos.[1]));
+                        let currState = stateStack.Peep()
+                        let newGotoState = gotoTable.Read(int tables.productionToNonTerminalTable.[prod], currState)
+                        stateStack.Push(newGotoState)
+#if DEBUG
+                        if Flags.debug then Console.WriteLine(" goto state {0}", newGotoState)
+#endif
+                    with                                                                                              
+                    | Accept res ->                                                                            
+                          finished <- true;                                                                             
+                          valueStack.Push(ValueInfo(res, lhsPos.[0], lhsPos.[1])) 
+                    | RecoverableParseError ->
+#if DEBUG
+                          if Flags.debug then Console.WriteLine("RecoverableParseErrorException...\n");
+#endif
+                          popStackUntilErrorShifted(None);
+                          // User code raised a Parse_error. Don't report errors again until three tokens have been shifted 
+                          errorSuppressionCountDown <- 3
+                elif kind = errorFlag then (
+#if DEBUG
+                    if Flags.debug then Console.Write("ErrorFlag... ");
+#endif
+                    // Silently discard inputs and don't report errors 
+                    // until three tokens in a row have been shifted 
+#if DEBUG
+                    if Flags.debug then printfn "error on token '%A' " (if haveLookahead then Some(lookaheadToken) else None);
+#endif
+                    if errorSuppressionCountDown > 0 then 
+                        // If we're in the end-of-file count down then we're very keen to 'Accept'.
+                        // We can only do this by repeatedly popping the stack until we can shift both an 'error' token
+                        // and an EOF token. 
+                        if inEofCountDown && eofCountDown < 10 then 
+#if DEBUG
+                            if Flags.debug then printfn "poppin stack, lokking to shift both 'error' and that token, during end-of-file error recovery" ;
+#endif
+                            popStackUntilErrorShifted(if haveLookahead then Some(lookaheadToken) else None);
+
+                        // If we don't haveLookahead then the end-of-file count down is over and we have no further options.
+                        if not haveLookahead then 
+                            failwith "parse error: unexpected end of file"
+                            
+#if DEBUG
+                        if Flags.debug then printfn "discarding token '%A' during error suppression" (if haveLookahead then Some(lookaheadToken) else None);
+#endif
+                        // Discard the token
+                        haveLookahead <- false
+                        // Try again to shift three tokens
+                        errorSuppressionCountDown <- 3
+                    else (
+
+                        let currentToken = if haveLookahead then Some(lookaheadToken) else None
+                        let actions,defaultAction = actionTable.ReadAll(state) 
+                        let explicit = Set.ofList [ for (tag,_action) in actions -> tag ]
+                        
+                        let shiftableTokens = 
+                           [ for (tag,action) in actions do
+                                 if (actionKind action) = shiftFlag then 
+                                     yield tag
+                             if actionKind defaultAction = shiftFlag  then
+                                 for tag in 0 .. tables.numTerminals-1 do  
+                                    if not (explicit.Contains(tag)) then 
+                                         yield tag ] in
+
+                        let stateStack = stateStack.Top(12) in
+                        let reducibleProductions = 
+                            [ for state in stateStack do 
+                               yield stateToProdIdxsTable.ReadAll(state)  ]
+
+                        let reduceTokens = 
+                           [ for (tag,action) in actions do
+                                if actionKind(action) = reduceFlag then
+                                    yield tag
+                             if actionKind(defaultAction) = reduceFlag  then
+                                 for tag in 0 .. tables.numTerminals-1 do  
+                                    if not (explicit.Contains(tag)) then 
+                                         yield tag ] in
+                        //let activeRules = stateStack |> List.iter (fun state -> 
+                        let errorContext = new ParseErrorContext<'tok>(stateStack,parseState, reduceTokens,currentToken,reducibleProductions, shiftableTokens, "syntax error")
+                        tables.parseError(errorContext);
+                        popStackUntilErrorShifted(None);
+                        errorSuppressionCountDown <- 3;
+#if DEBUG
+                        if Flags.debug then System.Console.WriteLine("generated syntax error and shifted error token, haveLookahead = {0}\n", haveLookahead);
+#endif
+                    )
+                ) elif kind = acceptFlag then 
+                    finished <- true
+#if DEBUG
+                else
+                  if Flags.debug then System.Console.WriteLine("ALARM!!! drop through case in parser");  
+#endif
+        done;                                                                                                     
+        // OK, we're done - read off the overall generated value
+        valueStack.Peep().value
+
+#if INTERNALIZED_POWER_PACK
+type internal Tables<'tok> with
+#else
+type Tables<'tok> with
+#endif
+    member tables.Interpret (lexer,lexbuf,initialState) = 
+        Implementation.interpret tables lexer lexbuf initialState
+    
+#if INTERNALIZED_POWER_PACK
+module internal ParseHelpers = 
+#else
+module ParseHelpers = 
+#endif
+    let parse_error (_s:string) = ()
+    let parse_error_rich = (None : (ParseErrorContext<_> -> unit) option)
--- fsharp-3.1.1.26+dfsg2.orig/FSharp.PowerPack/Parsing.fsi
+++ fsharp-3.1.1.26+dfsg2/FSharp.PowerPack/Parsing.fsi
@@ -1,130 +1,130 @@
-//==========================================================================
-// (c) Microsoft Corporation 2005-2009.
-//=========================================================================
-
-#if INTERNALIZED_POWER_PACK
-namespace Internal.Utilities.Text.Parsing
-open Internal.Utilities
-open Internal.Utilities.Text.Lexing
-#else
-namespace Microsoft.FSharp.Text.Parsing
-open Microsoft.FSharp.Text.Lexing
-#endif
-
-open System.Collections.Generic
-
-#if INTERNALIZED_POWER_PACK
-type internal IParseState = 
-#else
-/// The information accessible via the <c>parseState</c> value within parser actions.
-type IParseState = 
-#endif
-    /// Get the start and end position for the terminal or non-terminal at a given index matched by the production
-    abstract InputRange: index:int -> Position * Position
-    /// Get the end position for the terminal or non-terminal at a given index matched by the production
-    abstract InputEndPosition: int -> Position 
-    /// Get the start position for the terminal or non-terminal at a given index matched by the production
-    abstract InputStartPosition: int -> Position 
-    /// Get the full range of positions matched by the production
-    abstract ResultRange: Position * Position
-    /// Get the value produced by the terminal or non-terminal at the given position
-    abstract GetInput   : int -> obj 
-    /// Get the store of local values associated with this parser
-    // Dynamically typed, non-lexically scoped local store
-    abstract ParserLocalStore : IDictionary<string,obj>
-    /// Raise an error in this parse context
-    abstract RaiseError<'b> : unit -> 'b 
-
-
-[<Sealed>]
-#if INTERNALIZED_POWER_PACK
-type internal ParseErrorContext<'tok> =
-#else
-/// The context provided when a parse error occurs
-type ParseErrorContext<'tok> =
-#endif
-      /// The stack of state indexes active at the parse error 
-      member StateStack  : int list
-      /// The state active at the parse error 
-      member ParseState : IParseState
-      /// The tokens that would cause a reduction at the parse error 
-      member ReduceTokens: int list
-      /// The stack of productions that would be reduced at the parse error 
-      member ReducibleProductions : int list list
-      /// The token that caused the parse error
-      member CurrentToken : 'tok option
-      /// The token that would cause a shift at the parse error
-      member ShiftTokens : int list
-      /// The message associated with the parse error
-      member Message : string
-
-/// Tables generated by fsyacc
-#if INTERNALIZED_POWER_PACK
-type internal Tables<'tok> = 
-#else
-/// The type of the tables contained in a file produced by the fsyacc.exe parser generator.
-type Tables<'tok> = 
-#endif
-    { /// The reduction table
-      reductions: (IParseState -> obj) array ;
-      /// The token number indicating the end of input
-      endOfInputTag: int;
-      /// A function to compute the tag of a token
-      tagOfToken: 'tok -> int;
-      /// A function to compute the data carried by a token
-      dataOfToken: 'tok -> obj; 
-      /// The sparse action table elements
-      actionTableElements: uint16[];
-      /// The sparse action table row offsets
-      actionTableRowOffsets: uint16[];
-      /// The number of symbols for each reduction
-      reductionSymbolCounts: uint16[];
-      /// The immediate action table
-      immediateActions: uint16[];      
-      /// The sparse goto table
-      gotos: uint16[];
-      /// The sparse goto table row offsets
-      sparseGotoTableRowOffsets: uint16[];
-      /// The sparse table for the productions active for each state
-      stateToProdIdxsTableElements: uint16[];  
-      /// The sparse table offsets for the productions active for each state
-      stateToProdIdxsTableRowOffsets: uint16[];  
-      /// This table is logically part of the Goto table
-      productionToNonTerminalTable: uint16[];
-      /// This function is used to hold the user specified "parse_error" or "parse_error_rich" functions
-      parseError:  ParseErrorContext<'tok> -> unit;
-      /// The total number of terminals 
-      numTerminals: int;
-      /// The tag of the error terminal
-      tagOfErrorTerminal: int }
-
-    /// Interpret the parser table taking input from the given lexer, using the given lex buffer, and the given start state.
-    /// Returns an object indicating the final synthesized value for the parse.
-    member Interpret :  lexer:(LexBuffer<'char> -> 'tok) * lexbuf:LexBuffer<'char> * startState:int -> obj 
-
-#if INTERNALIZED_POWER_PACK
-exception internal Accept of obj
-exception internal RecoverableParseError
-#else
-/// Indicates an accept action has occured
-exception Accept of obj
-/// Indicates a parse error has occured and parse recovery is in progress
-exception RecoverableParseError
-#endif
-
-#if DEBUG
-module internal Flags =
-  val mutable debug : bool
-#endif
-
-#if INTERNALIZED_POWER_PACK
-module internal ParseHelpers = 
-#else
-/// Helpers used by generated parsers.
-module ParseHelpers = 
-#endif
-   /// The default implementation of the parse_error_rich function
-   val parse_error_rich: (ParseErrorContext<'tok> -> unit) option
-   /// The default implementation of the parse_error function
-   val parse_error: string -> unit
-
+//==========================================================================
+// (c) Microsoft Corporation 2005-2009.
+//=========================================================================
+
+#if INTERNALIZED_POWER_PACK
+namespace Internal.Utilities.Text.Parsing
+open Internal.Utilities
+open Internal.Utilities.Text.Lexing
+#else
+namespace Microsoft.FSharp.Text.Parsing
+open Microsoft.FSharp.Text.Lexing
+#endif
+
+open System.Collections.Generic
+
+#if INTERNALIZED_POWER_PACK
+type internal IParseState = 
+#else
+/// The information accessible via the <c>parseState</c> value within parser actions.
+type IParseState = 
+#endif
+    /// Get the start and end position for the terminal or non-terminal at a given index matched by the production
+    abstract InputRange: index:int -> Position * Position
+    /// Get the end position for the terminal or non-terminal at a given index matched by the production
+    abstract InputEndPosition: int -> Position 
+    /// Get the start position for the terminal or non-terminal at a given index matched by the production
+    abstract InputStartPosition: int -> Position 
+    /// Get the full range of positions matched by the production
+    abstract ResultRange: Position * Position
+    /// Get the value produced by the terminal or non-terminal at the given position
+    abstract GetInput   : int -> obj 
+    /// Get the store of local values associated with this parser
+    // Dynamically typed, non-lexically scoped local store
+    abstract ParserLocalStore : IDictionary<string,obj>
+    /// Raise an error in this parse context
+    abstract RaiseError<'b> : unit -> 'b 
+
+
+[<Sealed>]
+#if INTERNALIZED_POWER_PACK
+type internal ParseErrorContext<'tok> =
+#else
+/// The context provided when a parse error occurs
+type ParseErrorContext<'tok> =
+#endif
+      /// The stack of state indexes active at the parse error 
+      member StateStack  : int list
+      /// The state active at the parse error 
+      member ParseState : IParseState
+      /// The tokens that would cause a reduction at the parse error 
+      member ReduceTokens: int list
+      /// The stack of productions that would be reduced at the parse error 
+      member ReducibleProductions : int list list
+      /// The token that caused the parse error
+      member CurrentToken : 'tok option
+      /// The token that would cause a shift at the parse error
+      member ShiftTokens : int list
+      /// The message associated with the parse error
+      member Message : string
+
+/// Tables generated by fsyacc
+#if INTERNALIZED_POWER_PACK
+type internal Tables<'tok> = 
+#else
+/// The type of the tables contained in a file produced by the fsyacc.exe parser generator.
+type Tables<'tok> = 
+#endif
+    { /// The reduction table
+      reductions: (IParseState -> obj) array ;
+      /// The token number indicating the end of input
+      endOfInputTag: int;
+      /// A function to compute the tag of a token
+      tagOfToken: 'tok -> int;
+      /// A function to compute the data carried by a token
+      dataOfToken: 'tok -> obj; 
+      /// The sparse action table elements
+      actionTableElements: uint16[];
+      /// The sparse action table row offsets
+      actionTableRowOffsets: uint16[];
+      /// The number of symbols for each reduction
+      reductionSymbolCounts: uint16[];
+      /// The immediate action table
+      immediateActions: uint16[];      
+      /// The sparse goto table
+      gotos: uint16[];
+      /// The sparse goto table row offsets
+      sparseGotoTableRowOffsets: uint16[];
+      /// The sparse table for the productions active for each state
+      stateToProdIdxsTableElements: uint16[];  
+      /// The sparse table offsets for the productions active for each state
+      stateToProdIdxsTableRowOffsets: uint16[];  
+      /// This table is logically part of the Goto table
+      productionToNonTerminalTable: uint16[];
+      /// This function is used to hold the user specified "parse_error" or "parse_error_rich" functions
+      parseError:  ParseErrorContext<'tok> -> unit;
+      /// The total number of terminals 
+      numTerminals: int;
+      /// The tag of the error terminal
+      tagOfErrorTerminal: int }
+
+    /// Interpret the parser table taking input from the given lexer, using the given lex buffer, and the given start state.
+    /// Returns an object indicating the final synthesized value for the parse.
+    member Interpret :  lexer:(LexBuffer<'char> -> 'tok) * lexbuf:LexBuffer<'char> * startState:int -> obj 
+
+#if INTERNALIZED_POWER_PACK
+exception internal Accept of obj
+exception internal RecoverableParseError
+#else
+/// Indicates an accept action has occured
+exception Accept of obj
+/// Indicates a parse error has occured and parse recovery is in progress
+exception RecoverableParseError
+#endif
+
+#if DEBUG
+module internal Flags =
+  val mutable debug : bool
+#endif
+
+#if INTERNALIZED_POWER_PACK
+module internal ParseHelpers = 
+#else
+/// Helpers used by generated parsers.
+module ParseHelpers = 
+#endif
+   /// The default implementation of the parse_error_rich function
+   val parse_error_rich: (ParseErrorContext<'tok> -> unit) option
+   /// The default implementation of the parse_error function
+   val parse_error: string -> unit
+
--- fsharp-3.1.1.26+dfsg2.orig/FSharp.PowerPack/Permutation.fs
+++ fsharp-3.1.1.26+dfsg2/FSharp.PowerPack/Permutation.fs
@@ -1,56 +1,56 @@
-// (c) Microsoft Corporation 2005-2009. 
-
-namespace Microsoft.FSharp.Math
-
-type Permutation = int -> int
-
-type permutation = int -> int
-
-[<RequireQualifiedAccess>]
-[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
-module Permutation =
-
-    let invalidArg arg msg = raise (new System.ArgumentException((msg:string),(arg:string)))        
-
-    let ofFreshArray (arr:_[]) = 
-        let arr2 = Array.zeroCreate arr.Length
-        for i = 0 to arr.Length - 1 do 
-            let x = arr.[i] 
-            if x < 0 || x >= arr.Length then invalidArg "arr" "invalid permutation" 
-            arr2.[x] <- 1
-        for i = 0 to arr.Length - 1 do 
-            if arr2.[i] <> 1 then invalidArg "arr" "invalid permutation"
-        (fun k -> arr.[k])
-
-    let ofArray (arr:_[]) = arr |> Array.copy |> ofFreshArray
-
-    let of_array (arr:_[]) = ofArray arr
-
-    let ofPairs  (mappings: seq<int * int>) = 
-      let p = dict mappings 
-      (fun k -> if p.ContainsKey k then p.[k] else k)
-
-    let of_pairs  (mappings: seq<int * int>) =  ofPairs mappings
-
-    let swap (n:int) (m:int) = 
-      (fun k -> if k = n then m elif k = m then n else k)
-
-    let reversal size = 
-      if size <= 0 then invalidArg "size" "a permutation size must be positive";
-      (fun k -> (size - 1 - k))
-
-    let rotation size distance = 
-      if size <= 0 then invalidArg "size" "a permutation size must be positive";
-      if abs distance >= size then invalidArg "distance" "the absolute value of the distance must be less than the size of the permutation";
-      (fun k -> (k + size + distance) % size)
-
-    let identity (k:int) = k
-    
-    let inverse size p =
-        if size <= 0 then invalidArg "size" "a permutation size must be positive";
-        let arr2 = Array.zeroCreate size
-        for i = 0 to size - 1 do
-             arr2.[p i] <- i
-        ofFreshArray arr2
-
+// (c) Microsoft Corporation 2005-2009. 
+
+namespace Microsoft.FSharp.Math
+
+type Permutation = int -> int
+
+type permutation = int -> int
+
+[<RequireQualifiedAccess>]
+[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+module Permutation =
+
+    let invalidArg arg msg = raise (new System.ArgumentException((msg:string),(arg:string)))        
+
+    let ofFreshArray (arr:_[]) = 
+        let arr2 = Array.zeroCreate arr.Length
+        for i = 0 to arr.Length - 1 do 
+            let x = arr.[i] 
+            if x < 0 || x >= arr.Length then invalidArg "arr" "invalid permutation" 
+            arr2.[x] <- 1
+        for i = 0 to arr.Length - 1 do 
+            if arr2.[i] <> 1 then invalidArg "arr" "invalid permutation"
+        (fun k -> arr.[k])
+
+    let ofArray (arr:_[]) = arr |> Array.copy |> ofFreshArray
+
+    let of_array (arr:_[]) = ofArray arr
+
+    let ofPairs  (mappings: seq<int * int>) = 
+      let p = dict mappings 
+      (fun k -> if p.ContainsKey k then p.[k] else k)
+
+    let of_pairs  (mappings: seq<int * int>) =  ofPairs mappings
+
+    let swap (n:int) (m:int) = 
+      (fun k -> if k = n then m elif k = m then n else k)
+
+    let reversal size = 
+      if size <= 0 then invalidArg "size" "a permutation size must be positive";
+      (fun k -> (size - 1 - k))
+
+    let rotation size distance = 
+      if size <= 0 then invalidArg "size" "a permutation size must be positive";
+      if abs distance >= size then invalidArg "distance" "the absolute value of the distance must be less than the size of the permutation";
+      (fun k -> (k + size + distance) % size)
+
+    let identity (k:int) = k
+    
+    let inverse size p =
+        if size <= 0 then invalidArg "size" "a permutation size must be positive";
+        let arr2 = Array.zeroCreate size
+        for i = 0 to size - 1 do
+             arr2.[p i] <- i
+        ofFreshArray arr2
+
     
\ No newline at end of file
--- fsharp-3.1.1.26+dfsg2.orig/FSharp.PowerPack/Permutation.fsi
+++ fsharp-3.1.1.26+dfsg2/FSharp.PowerPack/Permutation.fsi
@@ -1,43 +1,43 @@
-// (c) Microsoft Corporation 2005-2009.
-namespace Microsoft.FSharp.Math
-
-/// A permutation of a finite range of integers 0 .. N-1, represented by a mapping of index positions
-type Permutation = int -> int
-
-[<System.Obsolete("This type abbreviation is now capitalized, please use 'Permutation'")>]
-type permutation = int -> int
-
-[<RequireQualifiedAccess>]
-[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
-module Permutation =
-    /// Create a permutation by specifying the result of permuting [| 0 .. n-1 |]. For example, 
-    /// Permutation.ofArray [| 1;2;0 |]  specifies a permutation that rotates all elements right one place.
-    val ofArray : destinations:int array -> Permutation
-    [<System.Obsolete("This function has been renamed. Use 'Permutation.ofArray' instead")>]
-    val of_array : destinations:int array -> Permutation
-
-    /// Create a permutation by specifying (source,destination) index pairs. For example,
-    /// Permutation(3,[ (0,2);(1,0); (2,1) ]) specifies a permutation that rotates 
-    /// all elements left one place. Not all elements need be given, e.g. 
-    /// Permutation(5,[ (1,2);(2,1) |]) specifies a permutation that swaps elements at indexes
-    /// 1 and 2.
-    val ofPairs : mappings: seq<int * int> -> Permutation
-
-    [<System.Obsolete("This function has been renamed. Use 'Permutation.ofPairs' instead")>]
-    val of_pairs : mappings: seq<int * int> -> Permutation
-    
-    /// Return a swaps the given two elements over any size
-    val swap: n:int -> m:int -> Permutation
-
-    /// Return a permutation that, when applied, maps index 0 to size-1, size-1 to 0 etc.
-    val reversal: size:int -> Permutation
-
-    /// Return a permutation that rotates right by the given distance. If the distance
-    /// is negative then a left rotation results.
-    val rotation: size:int -> distance:int -> Permutation
-    
-    /// The identity permutation over any size
-    val identity : Permutation
-    
-    val inverse : size: int -> p:Permutation -> Permutation
+// (c) Microsoft Corporation 2005-2009.
+namespace Microsoft.FSharp.Math
+
+/// A permutation of a finite range of integers 0 .. N-1, represented by a mapping of index positions
+type Permutation = int -> int
+
+[<System.Obsolete("This type abbreviation is now capitalized, please use 'Permutation'")>]
+type permutation = int -> int
+
+[<RequireQualifiedAccess>]
+[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+module Permutation =
+    /// Create a permutation by specifying the result of permuting [| 0 .. n-1 |]. For example, 
+    /// Permutation.ofArray [| 1;2;0 |]  specifies a permutation that rotates all elements right one place.
+    val ofArray : destinations:int array -> Permutation
+    [<System.Obsolete("This function has been renamed. Use 'Permutation.ofArray' instead")>]
+    val of_array : destinations:int array -> Permutation
+
+    /// Create a permutation by specifying (source,destination) index pairs. For example,
+    /// Permutation(3,[ (0,2);(1,0); (2,1) ]) specifies a permutation that rotates 
+    /// all elements left one place. Not all elements need be given, e.g. 
+    /// Permutation(5,[ (1,2);(2,1) |]) specifies a permutation that swaps elements at indexes
+    /// 1 and 2.
+    val ofPairs : mappings: seq<int * int> -> Permutation
+
+    [<System.Obsolete("This function has been renamed. Use 'Permutation.ofPairs' instead")>]
+    val of_pairs : mappings: seq<int * int> -> Permutation
+    
+    /// Return a swaps the given two elements over any size
+    val swap: n:int -> m:int -> Permutation
+
+    /// Return a permutation that, when applied, maps index 0 to size-1, size-1 to 0 etc.
+    val reversal: size:int -> Permutation
+
+    /// Return a permutation that rotates right by the given distance. If the distance
+    /// is negative then a left rotation results.
+    val rotation: size:int -> distance:int -> Permutation
+    
+    /// The identity permutation over any size
+    val identity : Permutation
+    
+    val inverse : size: int -> p:Permutation -> Permutation
     
\ No newline at end of file
--- fsharp-3.1.1.26+dfsg2.orig/FSharp.PowerPack/PhysicalConstants.fs
+++ fsharp-3.1.1.26+dfsg2/FSharp.PowerPack/PhysicalConstants.fs
@@ -1,91 +1,91 @@
-// (c) Microsoft Corporation 2005-2009. 
-
-namespace Microsoft.FSharp.Math
-
-open Microsoft.FSharp.Math.SI
-
-/// Fundamental physical constants, with units-of-measure
-// Selected from frequently used constants at http://physics.nist.gov/cuu/Constants/index.html
-module PhysicalConstants =
-
-  /// speed of light in vacuum
-  [<Literal>]
-  let c = 299792458.0<m/s>
-
-  /// magnetic constant
-  [<Literal>]
-  let mu0 = 12.566370614e-7<N A^-2>
-
-  /// electric constant = 1/(mu0 c^2)
-  [<Literal>]
-  let epsilon0 = 8.854187817e-12<F m^-1>
-
-  /// Newtonian constant of gravitation
-  [<Literal>]
-  let G = 6.6742867e-11<m^3 kg^-1 s^-2>
-  
-  /// Planck constant
-  [<Literal>]
-  let h = 6.6260689633e-34<J s>
-
-  /// Dirac constant, also known as the reduced Planck constant = h/2pi
-  [<Literal>]
-  let hbar = 1.05457162853e-34<J s>
-
-  /// Elementary charge
-  [<Literal>]
-  let e = 1.60217648740e-19<C>
-
-  /// Magnetic flux quantum h/2e
-  [<Literal>]
-  let Phi0 = 2.06783366752e-15<Wb>
-
-  /// Conductance quantum 2e^2/h
-  [<Literal>]
-  let G0 = 7.748091700453e-5<S>
-
-  /// Electron mass
-  [<Literal>]
-  let m_e = 9.1093821545e-31<kg>
-
-  /// Proton mass
-  [<Literal>]
-  let m_p = 1.67262163783e-27<kg>
-
-  /// Fine-structure constant
-  [<Literal>]
-  let alpha = 7.297352537650e-3
-
-  /// Rydberg constant
-  [<Literal>]
-  let R_inf = 10973731.56852773<m^-1>
-
-  /// Avogadro constant
-  [<Literal>]
-  let N_A = 6.0221417930e23<mol^-1>
-
-  /// Faraday constant
-  [<Literal>]
-  let F = 96485.339924<C/mol>
-
-  /// Molar gas constant
-  [<Literal>]
-  let R = 8.31447215<J mol^-1 K^-1> 
- 
-  /// Boltzmann constant R/N_A
-  [<Literal>]
-  let k = 1.380650424e-23<J/K>
-
-  /// Stefan-Boltzmann constant
-  [<Literal>]
-  let sigma = 5.67040040e-8<W m^-2 K^-4>
- 
-  /// Electron volt
-  [<Literal>]
-  let eV = 1.60217648740e-19<J>
-
-  /// Unified atomic mass unit
-  [<Literal>]
-  let u = 1.66053878283e-27<kg>
-
-
+// (c) Microsoft Corporation 2005-2009. 
+
+namespace Microsoft.FSharp.Math
+
+open Microsoft.FSharp.Math.SI
+
+/// Fundamental physical constants, with units-of-measure
+// Selected from frequently used constants at http://physics.nist.gov/cuu/Constants/index.html
+module PhysicalConstants =
+
+  /// speed of light in vacuum
+  [<Literal>]
+  let c = 299792458.0<m/s>
+
+  /// magnetic constant
+  [<Literal>]
+  let mu0 = 12.566370614e-7<N A^-2>
+
+  /// electric constant = 1/(mu0 c^2)
+  [<Literal>]
+  let epsilon0 = 8.854187817e-12<F m^-1>
+
+  /// Newtonian constant of gravitation
+  [<Literal>]
+  let G = 6.6742867e-11<m^3 kg^-1 s^-2>
+  
+  /// Planck constant
+  [<Literal>]
+  let h = 6.6260689633e-34<J s>
+
+  /// Dirac constant, also known as the reduced Planck constant = h/2pi
+  [<Literal>]
+  let hbar = 1.05457162853e-34<J s>
+
+  /// Elementary charge
+  [<Literal>]
+  let e = 1.60217648740e-19<C>
+
+  /// Magnetic flux quantum h/2e
+  [<Literal>]
+  let Phi0 = 2.06783366752e-15<Wb>
+
+  /// Conductance quantum 2e^2/h
+  [<Literal>]
+  let G0 = 7.748091700453e-5<S>
+
+  /// Electron mass
+  [<Literal>]
+  let m_e = 9.1093821545e-31<kg>
+
+  /// Proton mass
+  [<Literal>]
+  let m_p = 1.67262163783e-27<kg>
+
+  /// Fine-structure constant
+  [<Literal>]
+  let alpha = 7.297352537650e-3
+
+  /// Rydberg constant
+  [<Literal>]
+  let R_inf = 10973731.56852773<m^-1>
+
+  /// Avogadro constant
+  [<Literal>]
+  let N_A = 6.0221417930e23<mol^-1>
+
+  /// Faraday constant
+  [<Literal>]
+  let F = 96485.339924<C/mol>
+
+  /// Molar gas constant
+  [<Literal>]
+  let R = 8.31447215<J mol^-1 K^-1> 
+ 
+  /// Boltzmann constant R/N_A
+  [<Literal>]
+  let k = 1.380650424e-23<J/K>
+
+  /// Stefan-Boltzmann constant
+  [<Literal>]
+  let sigma = 5.67040040e-8<W m^-2 K^-4>
+ 
+  /// Electron volt
+  [<Literal>]
+  let eV = 1.60217648740e-19<J>
+
+  /// Unified atomic mass unit
+  [<Literal>]
+  let u = 1.66053878283e-27<kg>
+
+
--- fsharp-3.1.1.26+dfsg2.orig/FSharp.PowerPack/PowerPack.fs
+++ fsharp-3.1.1.26+dfsg2/FSharp.PowerPack/PowerPack.fs
@@ -1,35 +1,35 @@
-// (c) Microsoft Corporation 2005-2009. 
-
-module internal Microsoft.FSharp.AssemblyAttributes
-
-//[<assembly: System.Security.SecurityTransparent>]
-[<assembly: AutoOpen("Microsoft.FSharp.Compatibility")>]
-[<assembly: AutoOpen("Microsoft.FSharp.Compatibility.OCaml.Pervasives")>]
-[<assembly: AutoOpen("Microsoft.FSharp.Compatibility.OCaml")>]
-[<assembly: AutoOpen("Microsoft.FSharp.Text")>]
-[<assembly: AutoOpen("Microsoft.FSharp.Control")>]
-[<assembly: AutoOpen("Microsoft.FSharp.Collections")>]
-[<assembly: AutoOpen("Microsoft.FSharp.Core")>]
-[<assembly: AutoOpen("Microsoft.FSharp.Math")>]
-[<assembly: AutoOpen("Microsoft.FSharp")>]
-do()
-
-#if FX_NO_SECURITY_PERMISSIONS
-#else
-#if FX_SIMPLE_SECURITY_PERMISSIONS
-[<assembly: System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.RequestMinimum)>]
-#else
-#endif
-#endif
-
-[<assembly: System.Runtime.InteropServices.ComVisible(false)>]
-
-[<assembly: System.CLSCompliant(true)>]
-
-
-#if FX_NO_DEFAULT_DEPENDENCY_TYPE
-#else
-[<assembly: System.Runtime.CompilerServices.Dependency("FSharp.Core",System.Runtime.CompilerServices.LoadHint.Always)>] 
-#endif
-
-do ()
+// (c) Microsoft Corporation 2005-2009. 
+
+module internal Microsoft.FSharp.AssemblyAttributes
+
+//[<assembly: System.Security.SecurityTransparent>]
+[<assembly: AutoOpen("Microsoft.FSharp.Compatibility")>]
+[<assembly: AutoOpen("Microsoft.FSharp.Compatibility.OCaml.Pervasives")>]
+[<assembly: AutoOpen("Microsoft.FSharp.Compatibility.OCaml")>]
+[<assembly: AutoOpen("Microsoft.FSharp.Text")>]
+[<assembly: AutoOpen("Microsoft.FSharp.Control")>]
+[<assembly: AutoOpen("Microsoft.FSharp.Collections")>]
+[<assembly: AutoOpen("Microsoft.FSharp.Core")>]
+[<assembly: AutoOpen("Microsoft.FSharp.Math")>]
+[<assembly: AutoOpen("Microsoft.FSharp")>]
+do()
+
+#if FX_NO_SECURITY_PERMISSIONS
+#else
+#if FX_SIMPLE_SECURITY_PERMISSIONS
+[<assembly: System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.RequestMinimum)>]
+#else
+#endif
+#endif
+
+[<assembly: System.Runtime.InteropServices.ComVisible(false)>]
+
+[<assembly: System.CLSCompliant(true)>]
+
+
+#if FX_NO_DEFAULT_DEPENDENCY_TYPE
+#else
+[<assembly: System.Runtime.CompilerServices.Dependency("FSharp.Core",System.Runtime.CompilerServices.LoadHint.Always)>] 
+#endif
+
+do ()
--- fsharp-3.1.1.26+dfsg2.orig/FSharp.PowerPack/ResizeArray.fs
+++ fsharp-3.1.1.26+dfsg2/FSharp.PowerPack/ResizeArray.fs
@@ -1,321 +1,321 @@
-// (c) Microsoft Corporation 2005-2009. 
-
-namespace Microsoft.FSharp.Collections
-
-open Microsoft.FSharp.Core.OptimizedClosures
-
-
-[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
-module ResizeArray =
-
-    let length (arr: ResizeArray<'T>) =  arr.Count
-    let get (arr: ResizeArray<'T>) (n: int) =  arr.[n]
-    let set (arr: ResizeArray<'T>) (n: int) (x:'T) =  arr.[n] <- x
-    let create  (n: int) x = new ResizeArray<_> (seq { for _ in 1 .. n -> x })
-    let init (n: int) (f: int -> 'T) =  new ResizeArray<_> (seq { for i in 0 .. n-1 -> f i })
-
-    let blit (arr1: ResizeArray<'T>) start1 (arr2: ResizeArray<'T>) start2 len =
-        if start1 < 0 then invalidArg "start1" "index must be positive"
-        if start2 < 0 then invalidArg "start2" "index must be positive"
-        if len < 0 then invalidArg "len" "length must be positive"
-        if start1 + len > length arr1 then invalidArg "start1" "(start1+len) out of range"
-        if start2 + len > length arr2 then invalidArg "start2" "(start2+len) out of range"
-        for i = 0 to len - 1 do 
-            arr2.[start2+i] <- arr1.[start1 + i]
-
-    let concat (arrs: ResizeArray<'T> list) = new ResizeArray<_> (seq { for arr in arrs do for x in arr do yield x })
-    let append (arr1: ResizeArray<'T>) (arr2: ResizeArray<'T>) = concat [arr1; arr2]
-
-    let sub (arr: ResizeArray<'T>) start len =
-        if start < 0 then invalidArg "start" "index must be positive"
-        if len < 0 then invalidArg "len" "length must be positive"
-        if start + len > length arr then invalidArg "len" "length must be positive"
-        new ResizeArray<_> (seq { for i in start .. start+len-1 -> arr.[i] })
-
-    let fill (arr: ResizeArray<'T>) (start: int) (len: int) (x:'T) =
-        if start < 0 then invalidArg "start" "index must be positive"
-        if len < 0 then invalidArg "len" "length must be positive"
-        if start + len > length arr then invalidArg "len" "length must be positive"
-        for i = start to start + len - 1 do 
-            arr.[i] <- x
-
-    let copy      (arr: ResizeArray<'T>) = new ResizeArray<_>(arr)
-
-    let toList (arr: ResizeArray<_>) =
-        let mutable res = []
-        for i = length arr - 1 downto 0 do
-            res <- arr.[i] :: res
-        res
-
-    let ofList (l: _ list) =
-        let len = l.Length
-        let res = new ResizeArray<_>(len)
-        let rec add = function
-          | [] -> ()
-          | e::l -> res.Add(e); add l
-        add l
-        res
-
-    let ofSeq (s:seq<_>) = new ResizeArray<_>(s)
-        
-    let iter f (arr: ResizeArray<_>) = 
-        for i = 0 to arr.Count - 1 do
-            f arr.[i]
-
-    let map f (arr: ResizeArray<_>) =
-        let len = length arr
-        let res = new ResizeArray<_>(len)
-        for i = 0 to len - 1 do
-            res.Add(f arr.[i])
-        res
-
-    let mapi f (arr: ResizeArray<_>) =
-        let f = FSharpFunc<_,_,_>.Adapt(f)
-        let len = length arr
-        let res = new ResizeArray<_>(len)
-        for i = 0 to len - 1 do
-            res.Add(f.Invoke(i, arr.[i]))
-        res
-        
-    let iteri f (arr: ResizeArray<_>) =
-        let f = FSharpFunc<_,_,_>.Adapt(f)
-        for i = 0 to arr.Count - 1 do
-            f.Invoke(i, arr.[i])
-
-    let exists (f: 'T -> bool) (arr: ResizeArray<'T>) =
-        let len = length arr 
-        let rec loop i = i < len && (f arr.[i] || loop (i+1))
-        loop 0
-
-    let forall f (arr: ResizeArray<_>) =
-        let len = length arr
-        let rec loop i = i >= len || (f arr.[i] && loop (i+1))
-        loop 0
-
-    let indexNotFound() = raise (new System.Collections.Generic.KeyNotFoundException("An index satisfying the predicate was not found in the collection"))
-
-    let find f (arr: ResizeArray<_>) = 
-        let rec loop i = 
-            if i >= length arr then indexNotFound()
-            elif f arr.[i] then arr.[i]
-            else loop (i+1)
-        loop 0
-
-    let tryPick f (arr: ResizeArray<_>) =
-        let rec loop i = 
-            if i >= length arr then None else
-            match f arr.[i] with 
-            | None -> loop(i+1)
-            | res -> res
-        loop 0
-
-    let tryFind f (arr: ResizeArray<_>) = 
-        let rec loop i = 
-            if i >= length arr then None
-            elif f arr.[i] then Some arr.[i]
-            else loop (i+1)
-        loop 0
-
-    let iter2 f (arr1: ResizeArray<'T>) (arr2: ResizeArray<'b>) = 
-        let f = FSharpFunc<_,_,_>.Adapt(f)
-        let len1 = length arr1
-        if len1 <> length arr2 then invalidArg "arr2" "the arrays have different lengths"
-        for i = 0 to len1 - 1 do 
-            f.Invoke(arr1.[i], arr2.[i])
-
-    let map2 f (arr1: ResizeArray<'T>) (arr2: ResizeArray<'b>) = 
-        let f = FSharpFunc<_,_,_>.Adapt(f)
-        let len1 = length arr1
-        if len1 <> length arr2 then invalidArg "arr2" "the arrays have different lengths"
-        let res = new ResizeArray<_>(len1)
-        for i = 0 to len1 - 1 do
-            res.Add(f.Invoke(arr1.[i], arr2.[i]))
-        res
-
-    let choose f (arr: ResizeArray<_>) = 
-        let res = new ResizeArray<_>() 
-        for i = 0 to length arr - 1 do
-            match f arr.[i] with 
-            | None -> ()
-            | Some b -> res.Add(b)
-        res
-
-    let filter f (arr: ResizeArray<_>) = 
-        let res = new ResizeArray<_>() 
-        for i = 0 to length arr - 1 do 
-            let x = arr.[i] 
-            if f x then res.Add(x)
-        res
-
-    let partition f (arr: ResizeArray<_>) = 
-      let res1 = new ResizeArray<_>()
-      let res2 = new ResizeArray<_>()
-      for i = 0 to length arr - 1 do 
-          let x = arr.[i] 
-          if f x then res1.Add(x) else res2.Add(x)
-      res1, res2
-
-    let rev (arr: ResizeArray<_>) = 
-      let len = length arr 
-      let res = new ResizeArray<_>(len)
-      for i = len - 1 downto 0 do 
-          res.Add(arr.[i])
-      res
-
-    let foldBack (f : 'T -> 'State -> 'State) (arr: ResizeArray<'T>) (acc: 'State) =
-        let mutable res = acc 
-        let len = length arr 
-        for i = len - 1 downto 0 do 
-            res <- f (get arr i) res
-        res
-
-    let fold (f : 'State -> 'T -> 'State) (acc: 'State) (arr: ResizeArray<'T>) =
-        let mutable res = acc 
-        let len = length arr 
-        for i = 0 to len - 1 do 
-            res <- f res (get arr i)
-        res
-
-    let toArray (arr: ResizeArray<'T>) = arr.ToArray()
-    let ofArray (arr: 'T[]) = new ResizeArray<_>(arr)
-    let toSeq (arr: ResizeArray<'T>) = Seq.readonly arr
-
-    let sort f (arr: ResizeArray<'T>) = arr.Sort (System.Comparison(f))
-    let sortBy f (arr: ResizeArray<'T>) = arr.Sort (System.Comparison(fun x y -> compare (f x) (f y)))
-
-
-    let exists2 f (arr1: ResizeArray<_>) (arr2: ResizeArray<_>) =
-        let len1 = length arr1
-        if len1 <> length arr2 then invalidArg "arr2" "the arrays have different lengths"
-        let rec loop i = i < len1 && (f arr1.[i] arr2.[i] || loop (i+1))
-        loop 0
-
-    let findIndex f (arr: ResizeArray<_>) =
-        let rec go n = if n >= length arr then indexNotFound() elif f arr.[n] then n else go (n+1)
-        go 0
-
-    let findIndexi f (arr: ResizeArray<_>) =
-        let rec go n = if n >= length arr then indexNotFound() elif f n arr.[n] then n else go (n+1)
-        go 0
-
-    let foldSub f acc (arr: ResizeArray<_>) start fin = 
-        let mutable res = acc
-        for i = start to fin do
-            res <- f res arr.[i] 
-        res
-
-    let foldBackSub f (arr: ResizeArray<_>) start fin acc = 
-        let mutable res = acc 
-        for i = fin downto start do
-            res <- f arr.[i] res
-        res
-
-    let reduce f (arr : ResizeArray<_>) =
-        let arrn = length arr
-        if arrn = 0 then invalidArg "arr" "the input array may not be empty"
-        else foldSub f arr.[0] arr 1 (arrn - 1)
-        
-    let reduceBack f (arr: ResizeArray<_>) = 
-        let arrn = length arr
-        if arrn = 0 then invalidArg "arr" "the input array may not be empty"
-        else foldBackSub f arr 0 (arrn - 2) arr.[arrn - 1]
-
-    let fold2 f (acc: 'T) (arr1: ResizeArray<'T1>) (arr2: ResizeArray<'T2>) =
-        let f = FSharpFunc<_,_,_,_>.Adapt(f)
-        let mutable res = acc 
-        let len = length arr1
-        if len <> length arr2 then invalidArg "arr2" "the arrays have different lengths"
-        for i = 0 to len - 1 do
-            res <- f.Invoke(res,arr1.[i],arr2.[i])
-        res
-
-    let foldBack2 f (arr1: ResizeArray<'T1>) (arr2: ResizeArray<'T2>) (acc: 'b) =
-        let f = FSharpFunc<_,_,_,_>.Adapt(f)
-        let mutable res = acc 
-        let len = length arr1
-        if len <> length arr2 then invalidArg "arr2" "the arrays have different lengths"
-        for i = len - 1 downto 0 do 
-            res <- f.Invoke(arr1.[i],arr2.[i],res)
-        res
-
-    let forall2 f (arr1: ResizeArray<_>) (arr2: ResizeArray<_>) = 
-        let len1 = length arr1
-        if len1 <> length arr2 then invalidArg "arr2" "the arrays have different lengths"
-        let rec loop i = i >= len1 || (f arr1.[i] arr2.[i] && loop (i+1))
-        loop 0
-        
-    let isEmpty (arr: ResizeArray<_>) = length (arr: ResizeArray<_>) = 0
-    
-    let iteri2 f (arr1: ResizeArray<'T>) (arr2: ResizeArray<'b>) =
-        let f = FSharpFunc<_,_,_,_>.Adapt(f)
-        let len1 = length arr1
-        if len1 <> length arr2 then invalidArg "arr2" "the arrays have different lengths"
-        for i = 0 to len1 - 1 do 
-            f.Invoke(i,arr1.[i], arr2.[i])
-
-    let mapi2 (f: int -> 'T -> 'b -> 'c) (arr1: ResizeArray<'T>) (arr2: ResizeArray<'b>) = 
-        let f = FSharpFunc<_,_,_,_>.Adapt(f)
-        let len1 = length arr1
-        if len1 <> length arr2 then invalidArg "arr2" "the arrays have different lengths"
-        init len1 (fun i -> f.Invoke(i, arr1.[i], arr2.[i]))
-
-    let scanBackSub f (arr: ResizeArray<'T>) start fin acc = 
-        let f = FSharpFunc<_,_,_>.Adapt(f)
-        let mutable state = acc
-        let res = create (2+fin-start) acc
-        for i = fin downto start do
-            state <- f.Invoke(arr.[i], state)
-            res.[i - start] <- state
-        res
-
-    let scanSub f  acc (arr : ResizeArray<'T>) start fin = 
-        let f = FSharpFunc<_,_,_>.Adapt(f)
-        let mutable state = acc
-        let res = create (fin-start+2) acc
-        for i = start to fin do
-            state <- f.Invoke(state, arr.[i])
-            res.[i - start+1] <- state
-        res
-
-    let scan f acc (arr : ResizeArray<'T>) = 
-        let arrn = length arr
-        scanSub f acc arr 0 (arrn - 1)
-
-    let scanBack f (arr : ResizeArray<'T>) acc = 
-        let arrn = length arr
-        scanBackSub f arr 0 (arrn - 1) acc
-
-    let singleton x =
-        let res = new ResizeArray<_>(1)
-        res.Add(x)
-        res
-
-    let tryFindIndex f (arr: ResizeArray<'T>) = 
-        let rec go n = if n >= length arr then None elif f arr.[n] then Some n else go (n+1)
-        go 0
-        
-    let tryFindIndexi f (arr: ResizeArray<'T>) = 
-        let rec go n = if n >= length arr then None elif f n arr.[n] then Some n else go (n+1)
-        go 0
-    
-    let zip (arr1: ResizeArray<_>) (arr2: ResizeArray<_>) = 
-        let len1 = length arr1 
-        if len1 <> length arr2 then invalidArg "arr2" "the arrays have different lengths"
-        init len1 (fun i -> arr1.[i], arr2.[i])
-
-    let unzip (arr: ResizeArray<_>) = 
-        let len = length arr
-        let res1 = new ResizeArray<_>(len)
-        let res2 = new ResizeArray<_>(len)
-        for i = 0 to len - 1 do 
-            let x,y = arr.[i] 
-            res1.Add(x)
-            res2.Add(y)
-        res1,res2
-
-    let combine (arr1: ResizeArray<'T>) (arr2: ResizeArray<'b>) = zip arr1 arr2
-    let split (arr: ResizeArray<_>) = unzip arr
-
-    let to_list arr = toList arr
-    let of_list l = ofList l
-    let to_seq arr = toSeq arr
+// (c) Microsoft Corporation 2005-2009. 
+
+namespace Microsoft.FSharp.Collections
+
+open Microsoft.FSharp.Core.OptimizedClosures
+
+
+[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+module ResizeArray =
+
+    let length (arr: ResizeArray<'T>) =  arr.Count
+    let get (arr: ResizeArray<'T>) (n: int) =  arr.[n]
+    let set (arr: ResizeArray<'T>) (n: int) (x:'T) =  arr.[n] <- x
+    let create  (n: int) x = new ResizeArray<_> (seq { for _ in 1 .. n -> x })
+    let init (n: int) (f: int -> 'T) =  new ResizeArray<_> (seq { for i in 0 .. n-1 -> f i })
+
+    let blit (arr1: ResizeArray<'T>) start1 (arr2: ResizeArray<'T>) start2 len =
+        if start1 < 0 then invalidArg "start1" "index must be positive"
+        if start2 < 0 then invalidArg "start2" "index must be positive"
+        if len < 0 then invalidArg "len" "length must be positive"
+        if start1 + len > length arr1 then invalidArg "start1" "(start1+len) out of range"
+        if start2 + len > length arr2 then invalidArg "start2" "(start2+len) out of range"
+        for i = 0 to len - 1 do 
+            arr2.[start2+i] <- arr1.[start1 + i]
+
+    let concat (arrs: ResizeArray<'T> list) = new ResizeArray<_> (seq { for arr in arrs do for x in arr do yield x })
+    let append (arr1: ResizeArray<'T>) (arr2: ResizeArray<'T>) = concat [arr1; arr2]
+
+    let sub (arr: ResizeArray<'T>) start len =
+        if start < 0 then invalidArg "start" "index must be positive"
+        if len < 0 then invalidArg "len" "length must be positive"
+        if start + len > length arr then invalidArg "len" "length must be positive"
+        new ResizeArray<_> (seq { for i in start .. start+len-1 -> arr.[i] })
+
+    let fill (arr: ResizeArray<'T>) (start: int) (len: int) (x:'T) =
+        if start < 0 then invalidArg "start" "index must be positive"
+        if len < 0 then invalidArg "len" "length must be positive"
+        if start + len > length arr then invalidArg "len" "length must be positive"
+        for i = start to start + len - 1 do 
+            arr.[i] <- x
+
+    let copy      (arr: ResizeArray<'T>) = new ResizeArray<_>(arr)
+
+    let toList (arr: ResizeArray<_>) =
+        let mutable res = []
+        for i = length arr - 1 downto 0 do
+            res <- arr.[i] :: res
+        res
+
+    let ofList (l: _ list) =
+        let len = l.Length
+        let res = new ResizeArray<_>(len)
+        let rec add = function
+          | [] -> ()
+          | e::l -> res.Add(e); add l
+        add l
+        res
+
+    let ofSeq (s:seq<_>) = new ResizeArray<_>(s)
+        
+    let iter f (arr: ResizeArray<_>) = 
+        for i = 0 to arr.Count - 1 do
+            f arr.[i]
+
+    let map f (arr: ResizeArray<_>) =
+        let len = length arr
+        let res = new ResizeArray<_>(len)
+        for i = 0 to len - 1 do
+            res.Add(f arr.[i])
+        res
+
+    let mapi f (arr: ResizeArray<_>) =
+        let f = FSharpFunc<_,_,_>.Adapt(f)
+        let len = length arr
+        let res = new ResizeArray<_>(len)
+        for i = 0 to len - 1 do
+            res.Add(f.Invoke(i, arr.[i]))
+        res
+        
+    let iteri f (arr: ResizeArray<_>) =
+        let f = FSharpFunc<_,_,_>.Adapt(f)
+        for i = 0 to arr.Count - 1 do
+            f.Invoke(i, arr.[i])
+
+    let exists (f: 'T -> bool) (arr: ResizeArray<'T>) =
+        let len = length arr 
+        let rec loop i = i < len && (f arr.[i] || loop (i+1))
+        loop 0
+
+    let forall f (arr: ResizeArray<_>) =
+        let len = length arr
+        let rec loop i = i >= len || (f arr.[i] && loop (i+1))
+        loop 0
+
+    let indexNotFound() = raise (new System.Collections.Generic.KeyNotFoundException("An index satisfying the predicate was not found in the collection"))
+
+    let find f (arr: ResizeArray<_>) = 
+        let rec loop i = 
+            if i >= length arr then indexNotFound()
+            elif f arr.[i] then arr.[i]
+            else loop (i+1)
+        loop 0
+
+    let tryPick f (arr: ResizeArray<_>) =
+        let rec loop i = 
+            if i >= length arr then None else
+            match f arr.[i] with 
+            | None -> loop(i+1)
+            | res -> res
+        loop 0
+
+    let tryFind f (arr: ResizeArray<_>) = 
+        let rec loop i = 
+            if i >= length arr then None
+            elif f arr.[i] then Some arr.[i]
+            else loop (i+1)
+        loop 0
+
+    let iter2 f (arr1: ResizeArray<'T>) (arr2: ResizeArray<'b>) = 
+        let f = FSharpFunc<_,_,_>.Adapt(f)
+        let len1 = length arr1
+        if len1 <> length arr2 then invalidArg "arr2" "the arrays have different lengths"
+        for i = 0 to len1 - 1 do 
+            f.Invoke(arr1.[i], arr2.[i])
+
+    let map2 f (arr1: ResizeArray<'T>) (arr2: ResizeArray<'b>) = 
+        let f = FSharpFunc<_,_,_>.Adapt(f)
+        let len1 = length arr1
+        if len1 <> length arr2 then invalidArg "arr2" "the arrays have different lengths"
+        let res = new ResizeArray<_>(len1)
+        for i = 0 to len1 - 1 do
+            res.Add(f.Invoke(arr1.[i], arr2.[i]))
+        res
+
+    let choose f (arr: ResizeArray<_>) = 
+        let res = new ResizeArray<_>() 
+        for i = 0 to length arr - 1 do
+            match f arr.[i] with 
+            | None -> ()
+            | Some b -> res.Add(b)
+        res
+
+    let filter f (arr: ResizeArray<_>) = 
+        let res = new ResizeArray<_>() 
+        for i = 0 to length arr - 1 do 
+            let x = arr.[i] 
+            if f x then res.Add(x)
+        res
+
+    let partition f (arr: ResizeArray<_>) = 
+      let res1 = new ResizeArray<_>()
+      let res2 = new ResizeArray<_>()
+      for i = 0 to length arr - 1 do 
+          let x = arr.[i] 
+          if f x then res1.Add(x) else res2.Add(x)
+      res1, res2
+
+    let rev (arr: ResizeArray<_>) = 
+      let len = length arr 
+      let res = new ResizeArray<_>(len)
+      for i = len - 1 downto 0 do 
+          res.Add(arr.[i])
+      res
+
+    let foldBack (f : 'T -> 'State -> 'State) (arr: ResizeArray<'T>) (acc: 'State) =
+        let mutable res = acc 
+        let len = length arr 
+        for i = len - 1 downto 0 do 
+            res <- f (get arr i) res
+        res
+
+    let fold (f : 'State -> 'T -> 'State) (acc: 'State) (arr: ResizeArray<'T>) =
+        let mutable res = acc 
+        let len = length arr 
+        for i = 0 to len - 1 do 
+            res <- f res (get arr i)
+        res
+
+    let toArray (arr: ResizeArray<'T>) = arr.ToArray()
+    let ofArray (arr: 'T[]) = new ResizeArray<_>(arr)
+    let toSeq (arr: ResizeArray<'T>) = Seq.readonly arr
+
+    let sort f (arr: ResizeArray<'T>) = arr.Sort (System.Comparison(f))
+    let sortBy f (arr: ResizeArray<'T>) = arr.Sort (System.Comparison(fun x y -> compare (f x) (f y)))
+
+
+    let exists2 f (arr1: ResizeArray<_>) (arr2: ResizeArray<_>) =
+        let len1 = length arr1
+        if len1 <> length arr2 then invalidArg "arr2" "the arrays have different lengths"
+        let rec loop i = i < len1 && (f arr1.[i] arr2.[i] || loop (i+1))
+        loop 0
+
+    let findIndex f (arr: ResizeArray<_>) =
+        let rec go n = if n >= length arr then indexNotFound() elif f arr.[n] then n else go (n+1)
+        go 0
+
+    let findIndexi f (arr: ResizeArray<_>) =
+        let rec go n = if n >= length arr then indexNotFound() elif f n arr.[n] then n else go (n+1)
+        go 0
+
+    let foldSub f acc (arr: ResizeArray<_>) start fin = 
+        let mutable res = acc
+        for i = start to fin do
+            res <- f res arr.[i] 
+        res
+
+    let foldBackSub f (arr: ResizeArray<_>) start fin acc = 
+        let mutable res = acc 
+        for i = fin downto start do
+            res <- f arr.[i] res
+        res
+
+    let reduce f (arr : ResizeArray<_>) =
+        let arrn = length arr
+        if arrn = 0 then invalidArg "arr" "the input array may not be empty"
+        else foldSub f arr.[0] arr 1 (arrn - 1)
+        
+    let reduceBack f (arr: ResizeArray<_>) = 
+        let arrn = length arr
+        if arrn = 0 then invalidArg "arr" "the input array may not be empty"
+        else foldBackSub f arr 0 (arrn - 2) arr.[arrn - 1]
+
+    let fold2 f (acc: 'T) (arr1: ResizeArray<'T1>) (arr2: ResizeArray<'T2>) =
+        let f = FSharpFunc<_,_,_,_>.Adapt(f)
+        let mutable res = acc 
+        let len = length arr1
+        if len <> length arr2 then invalidArg "arr2" "the arrays have different lengths"
+        for i = 0 to len - 1 do
+            res <- f.Invoke(res,arr1.[i],arr2.[i])
+        res
+
+    let foldBack2 f (arr1: ResizeArray<'T1>) (arr2: ResizeArray<'T2>) (acc: 'b) =
+        let f = FSharpFunc<_,_,_,_>.Adapt(f)
+        let mutable res = acc 
+        let len = length arr1
+        if len <> length arr2 then invalidArg "arr2" "the arrays have different lengths"
+        for i = len - 1 downto 0 do 
+            res <- f.Invoke(arr1.[i],arr2.[i],res)
+        res
+
+    let forall2 f (arr1: ResizeArray<_>) (arr2: ResizeArray<_>) = 
+        let len1 = length arr1
+        if len1 <> length arr2 then invalidArg "arr2" "the arrays have different lengths"
+        let rec loop i = i >= len1 || (f arr1.[i] arr2.[i] && loop (i+1))
+        loop 0
+        
+    let isEmpty (arr: ResizeArray<_>) = length (arr: ResizeArray<_>) = 0
+    
+    let iteri2 f (arr1: ResizeArray<'T>) (arr2: ResizeArray<'b>) =
+        let f = FSharpFunc<_,_,_,_>.Adapt(f)
+        let len1 = length arr1
+        if len1 <> length arr2 then invalidArg "arr2" "the arrays have different lengths"
+        for i = 0 to len1 - 1 do 
+            f.Invoke(i,arr1.[i], arr2.[i])
+
+    let mapi2 (f: int -> 'T -> 'b -> 'c) (arr1: ResizeArray<'T>) (arr2: ResizeArray<'b>) = 
+        let f = FSharpFunc<_,_,_,_>.Adapt(f)
+        let len1 = length arr1
+        if len1 <> length arr2 then invalidArg "arr2" "the arrays have different lengths"
+        init len1 (fun i -> f.Invoke(i, arr1.[i], arr2.[i]))
+
+    let scanBackSub f (arr: ResizeArray<'T>) start fin acc = 
+        let f = FSharpFunc<_,_,_>.Adapt(f)
+        let mutable state = acc
+        let res = create (2+fin-start) acc
+        for i = fin downto start do
+            state <- f.Invoke(arr.[i], state)
+            res.[i - start] <- state
+        res
+
+    let scanSub f  acc (arr : ResizeArray<'T>) start fin = 
+        let f = FSharpFunc<_,_,_>.Adapt(f)
+        let mutable state = acc
+        let res = create (fin-start+2) acc
+        for i = start to fin do
+            state <- f.Invoke(state, arr.[i])
+            res.[i - start+1] <- state
+        res
+
+    let scan f acc (arr : ResizeArray<'T>) = 
+        let arrn = length arr
+        scanSub f acc arr 0 (arrn - 1)
+
+    let scanBack f (arr : ResizeArray<'T>) acc = 
+        let arrn = length arr
+        scanBackSub f arr 0 (arrn - 1) acc
+
+    let singleton x =
+        let res = new ResizeArray<_>(1)
+        res.Add(x)
+        res
+
+    let tryFindIndex f (arr: ResizeArray<'T>) = 
+        let rec go n = if n >= length arr then None elif f arr.[n] then Some n else go (n+1)
+        go 0
+        
+    let tryFindIndexi f (arr: ResizeArray<'T>) = 
+        let rec go n = if n >= length arr then None elif f n arr.[n] then Some n else go (n+1)
+        go 0
+    
+    let zip (arr1: ResizeArray<_>) (arr2: ResizeArray<_>) = 
+        let len1 = length arr1 
+        if len1 <> length arr2 then invalidArg "arr2" "the arrays have different lengths"
+        init len1 (fun i -> arr1.[i], arr2.[i])
+
+    let unzip (arr: ResizeArray<_>) = 
+        let len = length arr
+        let res1 = new ResizeArray<_>(len)
+        let res2 = new ResizeArray<_>(len)
+        for i = 0 to len - 1 do 
+            let x,y = arr.[i] 
+            res1.Add(x)
+            res2.Add(y)
+        res1,res2
+
+    let combine (arr1: ResizeArray<'T>) (arr2: ResizeArray<'b>) = zip arr1 arr2
+    let split (arr: ResizeArray<_>) = unzip arr
+
+    let to_list arr = toList arr
+    let of_list l = ofList l
+    let to_seq arr = toSeq arr
--- fsharp-3.1.1.26+dfsg2.orig/FSharp.PowerPack/ResizeArray.fsi
+++ fsharp-3.1.1.26+dfsg2/FSharp.PowerPack/ResizeArray.fsi
@@ -1,240 +1,240 @@
-//==========================================================================
-// ResizeArray
-// 
-// (c) Microsoft Corporation 2005-2008.  
-//===========================================================================
-
-namespace Microsoft.FSharp.Collections
-
-
-open System
-open System.Collections.Generic
-
-[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
-/// Generic operations on the type System.Collections.Generic.List, which is called ResizeArray in the F# libraries.
-module ResizeArray =
-
-    /// Return the length of the collection.  You can also use property <c>arr.Length</c>.
-    val length: ResizeArray<'T> -> int
-
-    /// Fetch an element from the collection.  You can also use the syntax <c>arr.[idx]</c>.
-    val get: ResizeArray<'T> -> int -> 'T
-
-
-    /// Set the value of an element in the collection. You can also use the syntax <c>arr.[idx] <- e</c>.
-    val set: ResizeArray<'T> -> int -> 'T -> unit
-
-    /// Create an array whose elements are all initially the given value.
-    val create: int -> 'T -> ResizeArray<'T>
-     
-    /// Create an array by calling the given generator on each index.
-    val init: int -> (int -> 'T) -> ResizeArray<'T>
-
-    ///Build a new array that contains the elements of the first array followed by the elements of the second array
-    val append: ResizeArray<'T> -> ResizeArray<'T> -> ResizeArray<'T>
-
-    ///Build a new array that contains the elements of each of the given list of arrays
-    val concat: ResizeArray<'T> list -> ResizeArray<'T>
-
-    ///Build a new array that contains the given subrange specified by
-    ///starting index and length.
-    val sub: ResizeArray<'T> -> int -> int -> ResizeArray<'T>
-
-    ///Build a new array that contains the elements of the given array
-    val copy: ResizeArray<'T> -> ResizeArray<'T>
-
-    ///Fill a range of the collection with the given element
-    val fill: ResizeArray<'T> -> int -> int -> 'T -> unit
-
-    ///Read a range of elements from the first array and write them into the second.
-    val blit: ResizeArray<'T> -> int -> ResizeArray<'T> -> int -> int -> unit
-
-    ///Build a list from the given array
-    val toList: ResizeArray<'T> -> 'T list
-    [<System.Obsolete("This function has been renamed. Use 'ResizeArray.toList' instead")>]
-    val to_list: ResizeArray<'T> -> 'T list
-
-    ///Build an array from the given list
-    val ofList: 'T list -> ResizeArray<'T>
-    [<System.Obsolete("This function has been renamed. Use 'ResizeArray.ofList' instead")>]
-    val of_list: 'T list -> ResizeArray<'T>
-
-    ///Build and array from the given seq
-    val ofSeq : 'T seq -> ResizeArray<'T>
-
-    /// Apply a function to each element of the collection, threading an accumulator argument
-    /// through the computation. If the input function is <c>f</c> and the elements are <c>i0...iN</c> 
-    /// then computes <c>f (... (f s i0)...) iN</c>
-    val fold: ('T -> 'U -> 'T) -> 'T -> ResizeArray<'U> -> 'T
-
-    /// Apply a function to each element of the array, threading an accumulator argument
-    /// through the computation. If the input function is <c>f</c> and the elements are <c>i0...iN</c> then 
-    /// computes <c>f i0 (...(f iN s))</c>.
-    val foldBack: ('T -> 'U -> 'U) -> ResizeArray<'T> -> 'U -> 'U
-
-    ///Apply the given function to each element of the array. 
-    val iter: ('T -> unit) -> ResizeArray<'T> -> unit
-
-    ///Build a new array whose elements are the results of applying the given function
-    ///to each of the elements of the array.
-    val map: ('T -> 'U) -> ResizeArray<'T> -> ResizeArray<'U>
-
-    ///Apply the given function to two arrays simultaneously. The
-    ///two arrays must have the same lengths, otherwise an Invalid_argument exception is
-    ///raised.
-    val iter2: ('T -> 'U -> unit) -> ResizeArray<'T> -> ResizeArray<'U> -> unit
-
-    ///Build a new collection whose elements are the results of applying the given function
-    ///to the corresponding elements of the two collections pairwise.  The two input
-    ///arrays must have the same lengths.
-    val map2: ('T -> 'U -> 'c) -> ResizeArray<'T> -> ResizeArray<'U> -> ResizeArray<'c>
-
-    ///Apply the given function to each element of the array.  The integer passed to the
-    ///function indicates the index of element.
-    val iteri: (int -> 'T -> unit) -> ResizeArray<'T> -> unit
-
-    ///Build a new array whose elements are the results of applying the given function
-    ///to each of the elements of the array. The integer index passed to the
-    ///function indicates the index of element being transformed.
-    val mapi: (int -> 'T -> 'U) -> ResizeArray<'T> -> ResizeArray<'U>
-
-    /// Test if any element of the array satisfies the given predicate.
-    /// If the input function is <c>f</c> and the elements are <c>i0...iN</c> 
-    /// then computes <c>p i0 or ... or p iN</c>.
-    val exists: ('T -> bool) -> ResizeArray<'T> -> bool
-
-    /// Test if all elements of the array satisfy the given predicate.
-    /// If the input function is <c>f</c> and the elements are <c>i0...iN</c> and "j0...jN"
-    /// then computes <c>p i0 && ... && p iN</c>.
-    val forall: ('T -> bool) -> ResizeArray<'T> -> bool
-
-    ///Return a new collection containing only the elements of the collection
-    ///for which the given predicate returns <c>true</c>
-    val filter: ('T -> bool) -> ResizeArray<'T> -> ResizeArray<'T>
-
-    ///Split the collection into two collections, containing the 
-    ///elements for which the given predicate returns <c>true</c> and <c>false</c>
-    ///respectively 
-    val partition: ('T -> bool) -> ResizeArray<'T> -> ResizeArray<'T> * ResizeArray<'T>
-
-    ///Apply the given function to each element of the array. Return
-    ///the array comprised of the results "x" for each element where
-    ///the function returns Some(x)
-    val choose: ('T -> 'U option) -> ResizeArray<'T> -> ResizeArray<'U>
-
-    ///Return the first element for which the given function returns <c>true</c>.
-    ///Raise <c>KeyNotFoundException</c> if no such element exists.
-    val find: ('T -> bool) -> ResizeArray<'T> -> 'T
-
-    ///Return the first element for which the given function returns <c>true</c>.
-    ///Return None if no such element exists.
-    val tryFind: ('T -> bool) -> ResizeArray<'T> -> 'T option
-
-    ///Apply the given function to successive elements, returning the first
-    ///result where function returns "Some(x)" for some x.
-    val tryPick: ('T -> 'U option) -> ResizeArray<'T> -> 'U option
-
-    ///Combine the two arrays into an array of pairs. The two arrays must have equal lengths.
-    [<Obsolete("Use unzip instead")>]
-    val combine: ResizeArray<'T> -> ResizeArray<'U> -> ResizeArray<('T * 'U)>
-
-    ///Split a list of pairs into two lists
-    [<Obsolete("Use unzip instead")>]
-    val split: ResizeArray<('T * 'U)> -> (ResizeArray<'T> * ResizeArray<'U>)
-
-    ///Return a new array with the elements in reverse order
-    val rev: ResizeArray<'T> -> ResizeArray<'T>
-
-    /// Sort the elements using the given comparison function
-    val sort: ('T -> 'T -> int) -> ResizeArray<'T> -> unit
-
-    /// Sort the elements using the key extractor and generic comparison on the keys
-    val sortBy: ('T -> 'Key) -> ResizeArray<'T> -> unit when 'Key : comparison
-
-    /// Return a fixed-length array containing the elements of the input ResizeArray
-    val toArray : ResizeArray<'T> -> 'T[]
-    /// Build a ResizeArray from the given elements
-    val ofArray : 'T[] -> ResizeArray<'T>
-    /// Return a view of the array as an enumerable object
-    val toSeq : ResizeArray<'T> -> seq<'T>
-    [<System.Obsolete("This function has been renamed. Use 'ResizeArray.toSeq' instead")>]
-    val to_seq : ResizeArray<'T> -> seq<'T>
-
-    /// Test elements of the two arrays pairwise to see if any pair of element satisfies the given predicate.
-    /// Raise ArgumentException if the arrays have different lengths.
-    val exists2 : ('T -> 'U -> bool) -> ResizeArray<'T> -> ResizeArray<'U> -> bool
-
-    /// Return the index of the first element in the array
-    /// that satisfies the given predicate. Raise <c>KeyNotFoundException</c> if 
-    /// none of the elements satisfy the predicate.
-    val findIndex : ('T -> bool) -> ResizeArray<'T> -> int
-
-    /// Return the index of the first element in the array
-    /// that satisfies the given predicate. Raise <c>KeyNotFoundException</c> if 
-    /// none of the elements satisfy the predicate.
-    val findIndexi : (int -> 'T -> bool) -> ResizeArray<'T> -> int
-
-    /// Apply a function to each element of the array, threading an accumulator argument
-    /// through the computation. If the input function is <c>f</c> and the elements are <c>i0...iN</c> 
-    /// then computes <c>f (... (f i0 i1)...) iN</c>. Raises ArgumentException if the array has size zero.
-    val reduce : ('T -> 'T -> 'T) -> ResizeArray<'T> -> 'T
-
-    /// Apply a function to each element of the array, threading an accumulator argument
-    /// through the computation. If the input function is <c>f</c> and the elements are <c>i0...iN</c> then 
-    /// computes <c>f i0 (...(f iN-1 iN))</c>. Raises ArgumentException if the array has size zero.
-    val reduceBack : ('T -> 'T -> 'T) -> ResizeArray<'T> -> 'T
-
-    /// Apply a function to pairs of elements drawn from the two collections, 
-    /// left-to-right, threading an accumulator argument
-    /// through the computation.  The two input
-    /// arrays must have the same lengths, otherwise an <c>ArgumentException</c> is
-    /// raised.
-    val fold2: ('state -> 'b1 -> 'b2 -> 'state) -> 'state -> ResizeArray<'b1> -> ResizeArray<'b2> -> 'state
-
-    /// Apply a function to pairs of elements drawn from the two collections, right-to-left, 
-    /// threading an accumulator argument through the computation.  The two input
-    /// arrays must have the same lengths, otherwise an <c>ArgumentException</c> is
-    /// raised.
-    val foldBack2 : ('a1 -> 'a2 -> 'U -> 'U) -> ResizeArray<'a1> -> ResizeArray<'a2> -> 'U -> 'U
-
-    /// Test elements of the two arrays pairwise to see if all pairs of elements satisfy the given predicate.
-    /// Raise ArgumentException if the arrays have different lengths.
-    val forall2 : ('T -> 'U -> bool) -> ResizeArray<'T> -> ResizeArray<'U> -> bool
-
-    /// Return true if the given array is empty, otherwise false
-    val isEmpty : ResizeArray<'T> -> bool
-
-    /// Apply the given function to pair of elements drawn from matching indices in two arrays,
-    /// also passing the index of the elements. The two arrays must have the same lengths, 
-    /// otherwise an <c>ArgumentException</c> is raised.
-    val iteri2 : (int -> 'T -> 'U -> unit) -> ResizeArray<'T> -> ResizeArray<'U> -> unit
-
-    /// Build a new collection whose elements are the results of applying the given function
-    /// to the corresponding elements of the two collections pairwise.  The two input
-    /// arrays must have the same lengths, otherwise an <c>ArgumentException</c> is
-    /// raised.
-    val mapi2 : (int -> 'T -> 'U -> 'c) -> ResizeArray<'T> -> ResizeArray<'U> -> ResizeArray<'c>
-
-    /// Like <c>fold</c>, but return the intermediary and final results
-    val scan : ('U -> 'T -> 'U) -> 'U -> ResizeArray<'T> -> ResizeArray<'U>
-
-    /// Like <c>foldBack</c>, but return both the intermediary and final results
-    val scanBack : ('T -> 'c -> 'c) -> ResizeArray<'T> -> 'c -> ResizeArray<'c>
-
-    /// Return an array containing the given element
-    val singleton : 'T -> ResizeArray<'T>
-    
-    /// Return the index of the first element in the array
-    /// that satisfies the given predicate.
-    val tryFindIndex : ('T -> bool) -> ResizeArray<'T> -> int option
-
-    /// Return the index of the first element in the array
-    /// that satisfies the given predicate.
-    val tryFindIndexi : (int -> 'T -> bool) -> ResizeArray<'T> -> int option
-
-    /// Combine the two arrays into an array of pairs. The two arrays must have equal lengths, otherwise an <c>ArgumentException</c> is
-    /// raised..
-    val zip : ResizeArray<'T> -> ResizeArray<'U> -> ResizeArray<'T * 'U>
-
-    /// Split an array of pairs into two arrays
-    val unzip : ResizeArray<'T * 'U> -> ResizeArray<'T> * ResizeArray<'U>
+//==========================================================================
+// ResizeArray
+// 
+// (c) Microsoft Corporation 2005-2008.  
+//===========================================================================
+
+namespace Microsoft.FSharp.Collections
+
+
+open System
+open System.Collections.Generic
+
+[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+/// Generic operations on the type System.Collections.Generic.List, which is called ResizeArray in the F# libraries.
+module ResizeArray =
+
+    /// Return the length of the collection.  You can also use property <c>arr.Length</c>.
+    val length: ResizeArray<'T> -> int
+
+    /// Fetch an element from the collection.  You can also use the syntax <c>arr.[idx]</c>.
+    val get: ResizeArray<'T> -> int -> 'T
+
+
+    /// Set the value of an element in the collection. You can also use the syntax <c>arr.[idx] <- e</c>.
+    val set: ResizeArray<'T> -> int -> 'T -> unit
+
+    /// Create an array whose elements are all initially the given value.
+    val create: int -> 'T -> ResizeArray<'T>
+     
+    /// Create an array by calling the given generator on each index.
+    val init: int -> (int -> 'T) -> ResizeArray<'T>
+
+    ///Build a new array that contains the elements of the first array followed by the elements of the second array
+    val append: ResizeArray<'T> -> ResizeArray<'T> -> ResizeArray<'T>
+
+    ///Build a new array that contains the elements of each of the given list of arrays
+    val concat: ResizeArray<'T> list -> ResizeArray<'T>
+
+    ///Build a new array that contains the given subrange specified by
+    ///starting index and length.
+    val sub: ResizeArray<'T> -> int -> int -> ResizeArray<'T>
+
+    ///Build a new array that contains the elements of the given array
+    val copy: ResizeArray<'T> -> ResizeArray<'T>
+
+    ///Fill a range of the collection with the given element
+    val fill: ResizeArray<'T> -> int -> int -> 'T -> unit
+
+    ///Read a range of elements from the first array and write them into the second.
+    val blit: ResizeArray<'T> -> int -> ResizeArray<'T> -> int -> int -> unit
+
+    ///Build a list from the given array
+    val toList: ResizeArray<'T> -> 'T list
+    [<System.Obsolete("This function has been renamed. Use 'ResizeArray.toList' instead")>]
+    val to_list: ResizeArray<'T> -> 'T list
+
+    ///Build an array from the given list
+    val ofList: 'T list -> ResizeArray<'T>
+    [<System.Obsolete("This function has been renamed. Use 'ResizeArray.ofList' instead")>]
+    val of_list: 'T list -> ResizeArray<'T>
+
+    ///Build and array from the given seq
+    val ofSeq : 'T seq -> ResizeArray<'T>
+
+    /// Apply a function to each element of the collection, threading an accumulator argument
+    /// through the computation. If the input function is <c>f</c> and the elements are <c>i0...iN</c> 
+    /// then computes <c>f (... (f s i0)...) iN</c>
+    val fold: ('T -> 'U -> 'T) -> 'T -> ResizeArray<'U> -> 'T
+
+    /// Apply a function to each element of the array, threading an accumulator argument
+    /// through the computation. If the input function is <c>f</c> and the elements are <c>i0...iN</c> then 
+    /// computes <c>f i0 (...(f iN s))</c>.
+    val foldBack: ('T -> 'U -> 'U) -> ResizeArray<'T> -> 'U -> 'U
+
+    ///Apply the given function to each element of the array. 
+    val iter: ('T -> unit) -> ResizeArray<'T> -> unit
+
+    ///Build a new array whose elements are the results of applying the given function
+    ///to each of the elements of the array.
+    val map: ('T -> 'U) -> ResizeArray<'T> -> ResizeArray<'U>
+
+    ///Apply the given function to two arrays simultaneously. The
+    ///two arrays must have the same lengths, otherwise an Invalid_argument exception is
+    ///raised.
+    val iter2: ('T -> 'U -> unit) -> ResizeArray<'T> -> ResizeArray<'U> -> unit
+
+    ///Build a new collection whose elements are the results of applying the given function
+    ///to the corresponding elements of the two collections pairwise.  The two input
+    ///arrays must have the same lengths.
+    val map2: ('T -> 'U -> 'c) -> ResizeArray<'T> -> ResizeArray<'U> -> ResizeArray<'c>
+
+    ///Apply the given function to each element of the array.  The integer passed to the
+    ///function indicates the index of element.
+    val iteri: (int -> 'T -> unit) -> ResizeArray<'T> -> unit
+
+    ///Build a new array whose elements are the results of applying the given function
+    ///to each of the elements of the array. The integer index passed to the
+    ///function indicates the index of element being transformed.
+    val mapi: (int -> 'T -> 'U) -> ResizeArray<'T> -> ResizeArray<'U>
+
+    /// Test if any element of the array satisfies the given predicate.
+    /// If the input function is <c>f</c> and the elements are <c>i0...iN</c> 
+    /// then computes <c>p i0 or ... or p iN</c>.
+    val exists: ('T -> bool) -> ResizeArray<'T> -> bool
+
+    /// Test if all elements of the array satisfy the given predicate.
+    /// If the input function is <c>f</c> and the elements are <c>i0...iN</c> and "j0...jN"
+    /// then computes <c>p i0 && ... && p iN</c>.
+    val forall: ('T -> bool) -> ResizeArray<'T> -> bool
+
+    ///Return a new collection containing only the elements of the collection
+    ///for which the given predicate returns <c>true</c>
+    val filter: ('T -> bool) -> ResizeArray<'T> -> ResizeArray<'T>
+
+    ///Split the collection into two collections, containing the 
+    ///elements for which the given predicate returns <c>true</c> and <c>false</c>
+    ///respectively 
+    val partition: ('T -> bool) -> ResizeArray<'T> -> ResizeArray<'T> * ResizeArray<'T>
+
+    ///Apply the given function to each element of the array. Return
+    ///the array comprised of the results "x" for each element where
+    ///the function returns Some(x)
+    val choose: ('T -> 'U option) -> ResizeArray<'T> -> ResizeArray<'U>
+
+    ///Return the first element for which the given function returns <c>true</c>.
+    ///Raise <c>KeyNotFoundException</c> if no such element exists.
+    val find: ('T -> bool) -> ResizeArray<'T> -> 'T
+
+    ///Return the first element for which the given function returns <c>true</c>.
+    ///Return None if no such element exists.
+    val tryFind: ('T -> bool) -> ResizeArray<'T> -> 'T option
+
+    ///Apply the given function to successive elements, returning the first
+    ///result where function returns "Some(x)" for some x.
+    val tryPick: ('T -> 'U option) -> ResizeArray<'T> -> 'U option
+
+    ///Combine the two arrays into an array of pairs. The two arrays must have equal lengths.
+    [<Obsolete("Use unzip instead")>]
+    val combine: ResizeArray<'T> -> ResizeArray<'U> -> ResizeArray<('T * 'U)>
+
+    ///Split a list of pairs into two lists
+    [<Obsolete("Use unzip instead")>]
+    val split: ResizeArray<('T * 'U)> -> (ResizeArray<'T> * ResizeArray<'U>)
+
+    ///Return a new array with the elements in reverse order
+    val rev: ResizeArray<'T> -> ResizeArray<'T>
+
+    /// Sort the elements using the given comparison function
+    val sort: ('T -> 'T -> int) -> ResizeArray<'T> -> unit
+
+    /// Sort the elements using the key extractor and generic comparison on the keys
+    val sortBy: ('T -> 'Key) -> ResizeArray<'T> -> unit when 'Key : comparison
+
+    /// Return a fixed-length array containing the elements of the input ResizeArray
+    val toArray : ResizeArray<'T> -> 'T[]
+    /// Build a ResizeArray from the given elements
+    val ofArray : 'T[] -> ResizeArray<'T>
+    /// Return a view of the array as an enumerable object
+    val toSeq : ResizeArray<'T> -> seq<'T>
+    [<System.Obsolete("This function has been renamed. Use 'ResizeArray.toSeq' instead")>]
+    val to_seq : ResizeArray<'T> -> seq<'T>
+
+    /// Test elements of the two arrays pairwise to see if any pair of element satisfies the given predicate.
+    /// Raise ArgumentException if the arrays have different lengths.
+    val exists2 : ('T -> 'U -> bool) -> ResizeArray<'T> -> ResizeArray<'U> -> bool
+
+    /// Return the index of the first element in the array
+    /// that satisfies the given predicate. Raise <c>KeyNotFoundException</c> if 
+    /// none of the elements satisfy the predicate.
+    val findIndex : ('T -> bool) -> ResizeArray<'T> -> int
+
+    /// Return the index of the first element in the array
+    /// that satisfies the given predicate. Raise <c>KeyNotFoundException</c> if 
+    /// none of the elements satisfy the predicate.
+    val findIndexi : (int -> 'T -> bool) -> ResizeArray<'T> -> int
+
+    /// Apply a function to each element of the array, threading an accumulator argument
+    /// through the computation. If the input function is <c>f</c> and the elements are <c>i0...iN</c> 
+    /// then computes <c>f (... (f i0 i1)...) iN</c>. Raises ArgumentException if the array has size zero.
+    val reduce : ('T -> 'T -> 'T) -> ResizeArray<'T> -> 'T
+
+    /// Apply a function to each element of the array, threading an accumulator argument
+    /// through the computation. If the input function is <c>f</c> and the elements are <c>i0...iN</c> then 
+    /// computes <c>f i0 (...(f iN-1 iN))</c>. Raises ArgumentException if the array has size zero.
+    val reduceBack : ('T -> 'T -> 'T) -> ResizeArray<'T> -> 'T
+
+    /// Apply a function to pairs of elements drawn from the two collections, 
+    /// left-to-right, threading an accumulator argument
+    /// through the computation.  The two input
+    /// arrays must have the same lengths, otherwise an <c>ArgumentException</c> is
+    /// raised.
+    val fold2: ('state -> 'b1 -> 'b2 -> 'state) -> 'state -> ResizeArray<'b1> -> ResizeArray<'b2> -> 'state
+
+    /// Apply a function to pairs of elements drawn from the two collections, right-to-left, 
+    /// threading an accumulator argument through the computation.  The two input
+    /// arrays must have the same lengths, otherwise an <c>ArgumentException</c> is
+    /// raised.
+    val foldBack2 : ('a1 -> 'a2 -> 'U -> 'U) -> ResizeArray<'a1> -> ResizeArray<'a2> -> 'U -> 'U
+
+    /// Test elements of the two arrays pairwise to see if all pairs of elements satisfy the given predicate.
+    /// Raise ArgumentException if the arrays have different lengths.
+    val forall2 : ('T -> 'U -> bool) -> ResizeArray<'T> -> ResizeArray<'U> -> bool
+
+    /// Return true if the given array is empty, otherwise false
+    val isEmpty : ResizeArray<'T> -> bool
+
+    /// Apply the given function to pair of elements drawn from matching indices in two arrays,
+    /// also passing the index of the elements. The two arrays must have the same lengths, 
+    /// otherwise an <c>ArgumentException</c> is raised.
+    val iteri2 : (int -> 'T -> 'U -> unit) -> ResizeArray<'T> -> ResizeArray<'U> -> unit
+
+    /// Build a new collection whose elements are the results of applying the given function
+    /// to the corresponding elements of the two collections pairwise.  The two input
+    /// arrays must have the same lengths, otherwise an <c>ArgumentException</c> is
+    /// raised.
+    val mapi2 : (int -> 'T -> 'U -> 'c) -> ResizeArray<'T> -> ResizeArray<'U> -> ResizeArray<'c>
+
+    /// Like <c>fold</c>, but return the intermediary and final results
+    val scan : ('U -> 'T -> 'U) -> 'U -> ResizeArray<'T> -> ResizeArray<'U>
+
+    /// Like <c>foldBack</c>, but return both the intermediary and final results
+    val scanBack : ('T -> 'c -> 'c) -> ResizeArray<'T> -> 'c -> ResizeArray<'c>
+
+    /// Return an array containing the given element
+    val singleton : 'T -> ResizeArray<'T>
+    
+    /// Return the index of the first element in the array
+    /// that satisfies the given predicate.
+    val tryFindIndex : ('T -> bool) -> ResizeArray<'T> -> int option
+
+    /// Return the index of the first element in the array
+    /// that satisfies the given predicate.
+    val tryFindIndexi : (int -> 'T -> bool) -> ResizeArray<'T> -> int option
+
+    /// Combine the two arrays into an array of pairs. The two arrays must have equal lengths, otherwise an <c>ArgumentException</c> is
+    /// raised..
+    val zip : ResizeArray<'T> -> ResizeArray<'U> -> ResizeArray<'T * 'U>
+
+    /// Split an array of pairs into two arrays
+    val unzip : ResizeArray<'T * 'U> -> ResizeArray<'T> * ResizeArray<'U>
--- fsharp-3.1.1.26+dfsg2.orig/FSharp.PowerPack/SI.fs
+++ fsharp-3.1.1.26+dfsg2/FSharp.PowerPack/SI.fs
@@ -1,113 +1,113 @@
-// (c) Microsoft Corporation 2005-2009. 
-
-namespace Microsoft.FSharp.Math
-
-
-// System Internationale. See http://www.bipm.org/en/si/si_brochure/general.html
-/// The International System of Units (SI)
-[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
-module SI =
-
-  [<Measure>] 
-  /// metre (or meter), SI unit of length
-  type m               
-
-  [<Measure>] 
-  /// kilogram, SI unit of mass
-  type kg
-
-  [<Measure>] 
-  /// second, SI unit of time
-  type s
-
-  [<Measure>] 
-  /// ampere, SI unit of electric current
-  type A             
-
-  [<Measure>] 
-  /// kelvin, SI unit of thermodynamic temperature
-  type K              
-
-  [<Measure>] 
-  /// mole, SI unit of amount of substance
-  type mol             
-
-  [<Measure>] 
-  /// candela, SI unit of luminous intensity
-  type cd              
-
-  [<Measure>] 
-  /// hertz, SI unit of frequency
-  type Hz = s^-1
-
-  [<Measure>] 
-  /// newton, SI unit of force
-  type N = kg m / s^2 
-
-  [<Measure>] 
-  /// pascal, SI unit of pressure, stress
-  type Pa = N / m^2
-
-  [<Measure>] 
-  /// joule, SI unit of energy, work, amount of heat
-  type J = N m
-
-  [<Measure>] 
-  /// watt, SI unit of power, radiant flux
-  type W = J / s       
-
-  [<Measure>] 
-  /// coulomb, SI unit of electric charge, amount of electricity
-  type C = s A 
-
-  [<Measure>] 
-  /// volt, SI unit of electric potential difference, electromotive force
-  type V = W/A        
-
-  [<Measure>] 
-  /// farad, SI unit of capacitance
-  type F = C/V
-
-  [<Measure>] 
-  /// ohm, SI unit of electric resistance
-  type ohm = V/A       
-
-  [<Measure>] 
-  /// siemens, SI unit of electric conductance
-  type S = A/V         
-
-  [<Measure>] 
-  /// weber, SI unit of magnetic flux
-  type Wb = V s        
-
-  [<Measure>] 
-  /// tesla, SI unit of magnetic flux density
-  type T = Wb/m^2      
-
-  [<Measure>] 
-  /// henry, SI unit of inductance
-  type H = Wb/A        
-
-  [<Measure>] 
-  /// lumen, SI unit of luminous flux
-  type lm = cd        
-
-  [<Measure>] 
-  /// lux, SI unit of illuminance
-  type lx = lm/m^2 
-
-  [<Measure>] 
-  /// becquerel, SI unit of activity referred to a radionuclide
-  type Bq = s^-1       
-
-  [<Measure>] 
-  /// gray, SI unit of absorbed dose
-  type Gy = J/kg       
-
-  [<Measure>] 
-  /// sievert, SI unit of does equivalent
-  type Sv = J/kg       
-
-  [<Measure>] 
-  /// katal, SI unit of catalytic activity
-  type kat = mol/s 
+// (c) Microsoft Corporation 2005-2009. 
+
+namespace Microsoft.FSharp.Math
+
+
+// System Internationale. See http://www.bipm.org/en/si/si_brochure/general.html
+/// The International System of Units (SI)
+[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+module SI =
+
+  [<Measure>] 
+  /// metre (or meter), SI unit of length
+  type m               
+
+  [<Measure>] 
+  /// kilogram, SI unit of mass
+  type kg
+
+  [<Measure>] 
+  /// second, SI unit of time
+  type s
+
+  [<Measure>] 
+  /// ampere, SI unit of electric current
+  type A             
+
+  [<Measure>] 
+  /// kelvin, SI unit of thermodynamic temperature
+  type K              
+
+  [<Measure>] 
+  /// mole, SI unit of amount of substance
+  type mol             
+
+  [<Measure>] 
+  /// candela, SI unit of luminous intensity
+  type cd              
+
+  [<Measure>] 
+  /// hertz, SI unit of frequency
+  type Hz = s^-1
+
+  [<Measure>] 
+  /// newton, SI unit of force
+  type N = kg m / s^2 
+
+  [<Measure>] 
+  /// pascal, SI unit of pressure, stress
+  type Pa = N / m^2
+
+  [<Measure>] 
+  /// joule, SI unit of energy, work, amount of heat
+  type J = N m
+
+  [<Measure>] 
+  /// watt, SI unit of power, radiant flux
+  type W = J / s       
+
+  [<Measure>] 
+  /// coulomb, SI unit of electric charge, amount of electricity
+  type C = s A 
+
+  [<Measure>] 
+  /// volt, SI unit of electric potential difference, electromotive force
+  type V = W/A        
+
+  [<Measure>] 
+  /// farad, SI unit of capacitance
+  type F = C/V
+
+  [<Measure>] 
+  /// ohm, SI unit of electric resistance
+  type ohm = V/A       
+
+  [<Measure>] 
+  /// siemens, SI unit of electric conductance
+  type S = A/V         
+
+  [<Measure>] 
+  /// weber, SI unit of magnetic flux
+  type Wb = V s        
+
+  [<Measure>] 
+  /// tesla, SI unit of magnetic flux density
+  type T = Wb/m^2      
+
+  [<Measure>] 
+  /// henry, SI unit of inductance
+  type H = Wb/A        
+
+  [<Measure>] 
+  /// lumen, SI unit of luminous flux
+  type lm = cd        
+
+  [<Measure>] 
+  /// lux, SI unit of illuminance
+  type lx = lm/m^2 
+
+  [<Measure>] 
+  /// becquerel, SI unit of activity referred to a radionuclide
+  type Bq = s^-1       
+
+  [<Measure>] 
+  /// gray, SI unit of absorbed dose
+  type Gy = J/kg       
+
+  [<Measure>] 
+  /// sievert, SI unit of does equivalent
+  type Sv = J/kg       
+
+  [<Measure>] 
+  /// katal, SI unit of catalytic activity
+  type kat = mol/s 
--- fsharp-3.1.1.26+dfsg2.orig/FSharp.PowerPack/StructuredFormat.fs
+++ fsharp-3.1.1.26+dfsg2/FSharp.PowerPack/StructuredFormat.fs
@@ -1,1020 +1,1020 @@
-//=========================================================================
-// (c) Microsoft Corporation 2005-2009. 
-//=========================================================================
-
-#nowarn "52" // The value has been copied to ensure the original is not mutated by this operation
-
-namespace Microsoft.FSharp.Text.StructuredFormat
-
-    // Breakable block layout implementation.
-    // This is a fresh implementation of pre-existing ideas.
-
-    open System
-    open System.Diagnostics
-    open System.Text
-    open System.IO
-    open System.Reflection
-    open System.Globalization
-    open System.Collections.Generic
-    open Microsoft.FSharp.Reflection
-
-    /// A joint, between 2 layouts, is either:
-    ///  - unbreakable, or
-    ///  - breakable, and if broken the second block has a given indentation.
-    [<StructuralEquality; NoComparison>]
-    type Joint =
-     | Unbreakable
-     | Breakable of int
-     | Broken of int
-
-    /// Leaf juxt,data,juxt
-    /// Node juxt,left,juxt,right,juxt and joint
-    ///
-    /// If either juxt flag is true, then no space between words.
-    [<NoEquality; NoComparison>]
-    type Layout =
-     | Leaf of bool * obj * bool
-     | Node of bool * layout * bool * layout * bool * joint
-     | Attr of string * (string * string) list * layout
-
-    and layout = Layout
-
-    and joint = Joint
-
-    [<NoEquality; NoComparison>]
-    type IEnvironment = 
-        abstract GetLayout : obj -> layout
-        abstract MaxColumns : int
-        abstract MaxRows : int
-     
-    [<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
-    module LayoutOps = 
-        let rec juxtLeft = function
-          | Leaf (jl,_,_)         -> jl
-          | Node (jl,_,_,_,_,_) -> jl
-          | Attr (_,_,l)        -> juxtLeft l
-
-        let rec juxtRight = function
-          | Leaf (_,_,jr)         -> jr
-          | Node (_,_,_,_,jr,_) -> jr
-          | Attr (_,_,l)        -> juxtRight l
-
-        let mkNode l r joint =
-           let jl = juxtLeft  l 
-           let jm = juxtRight l || juxtLeft r 
-           let jr = juxtRight r 
-           Node(jl,l,jm,r,jr,joint)
-
-
-        // constructors
-
-
-        let objL   (obj:obj) = Leaf (false,obj,false)
-        let sLeaf  (l,(str:string),r) = Leaf (l,(str:>obj),r)
-        let wordL  str = sLeaf (false,str,false)
-        let sepL   str = sLeaf (true ,str,true)   
-        let rightL str = sLeaf (true ,str,false)   
-        let leftL  str = sLeaf (false,str,true)
-        let emptyL = sLeaf (true,"",true)
-        let isEmptyL = function 
-         | Leaf(true,s,true) -> 
-            match s with 
-            | :? string as s -> s = "" 
-            | _ -> false
-         | _ -> false
-         
-
-        let aboveL  l r = mkNode l r (Broken 0)
-
-        let joinN i l r = mkNode l r (Breakable i)                                      
-        let join  = joinN 0
-        let join1 = joinN 1
-        let join2 = joinN 2
-        let join3 = joinN 3
-
-        let tagAttrL tag attrs l = Attr(tag,attrs,l)
-
-        let apply2 f l r = if isEmptyL l then r else
-                           if isEmptyL r then l else f l r
-
-        let (^^)  l r  = mkNode l r (Unbreakable)
-        let (++)  l r  = mkNode l r (Breakable 0)
-        let (--)  l r  = mkNode l r (Breakable 1)
-        let (---) l r  = mkNode l r (Breakable 2)
-        let (@@)   l r = apply2 (fun l r -> mkNode l r (Broken 0)) l r
-        let (@@-)  l r = apply2 (fun l r -> mkNode l r (Broken 1)) l r
-        let (@@--) l r = apply2 (fun l r -> mkNode l r (Broken 2)) l r
-        let tagListL tagger = function
-            | []    -> emptyL
-            | [x]   -> x
-            | x::xs ->
-                let rec process' prefixL = function
-                    []    -> prefixL
-                  | y::ys -> process' ((tagger prefixL) ++ y) ys
-                in  process' x xs
-            
-        let commaListL x = tagListL (fun prefixL -> prefixL ^^ rightL ",") x
-        let semiListL x  = tagListL (fun prefixL -> prefixL ^^ rightL ";") x
-        let spaceListL x = tagListL (fun prefixL -> prefixL) x
-        let sepListL x y = tagListL (fun prefixL -> prefixL ^^ x) y
-        let bracketL l = leftL "(" ^^ l ^^ rightL ")"
-        let tupleL xs = bracketL (sepListL (sepL ",") xs)
-        let aboveListL = function
-          | []    -> emptyL
-          | [x]   -> x
-          | x::ys -> List.fold (fun pre y -> pre @@ y) x ys
-
-        let optionL xL = function
-            None   -> wordL "None"
-          | Some x -> wordL "Some" -- (xL x)
-
-        let listL xL xs = leftL "[" ^^ sepListL (sepL ";") (List.map xL xs) ^^ rightL "]"
-
-        let squareBracketL x = leftL "[" ^^ x ^^ rightL "]"    
-
-        let braceL         x = leftL "{" ^^ x ^^ rightL "}"
-
-        let boundedUnfoldL
-                    (itemL     : 'a -> layout)
-                    (project   : 'z -> ('a * 'z) option)
-                    (stopShort : 'z -> bool)
-                    (z : 'z)
-                    maxLength =
-          let rec consume n z =
-            if stopShort z then [wordL "..."] else
-            match project z with
-              | None       -> []  (* exhaused input *)
-              | Some (x,z) -> if n<=0 then [wordL "..."]               (* hit print_length limit *)
-                                      else itemL x :: consume (n-1) z  (* cons recursive... *)
-          consume maxLength z  
-
-        let unfoldL itemL project z maxLength = boundedUnfoldL  itemL project (fun _ -> false) z maxLength
-          
-    /// These are a typical set of options used to control structured formatting.
-    [<NoEquality; NoComparison>]
-    type FormatOptions = 
-        { FloatingPointFormat: string;
-          AttributeProcessor: (string -> (string * string) list -> bool -> unit);
-          FormatProvider: System.IFormatProvider;
-          BindingFlags: System.Reflection.BindingFlags
-          PrintWidth : int; 
-          PrintDepth : int; 
-          PrintLength : int;
-          PrintSize : int;        
-          ShowProperties : bool;
-          ShowIEnumerable: bool; }
-        static member Default =
-            { FormatProvider = (System.Globalization.CultureInfo.InvariantCulture :> System.IFormatProvider);
-              AttributeProcessor= (fun _ _ _ -> ());
-              BindingFlags = System.Reflection.BindingFlags.Public;
-              FloatingPointFormat = "g10";
-              PrintWidth = 80 ; 
-              PrintDepth = 100 ; 
-              PrintLength = 100;
-              PrintSize = 10000;
-              ShowProperties = false;
-              ShowIEnumerable = true; }
-
-
-
-    module ReflectUtils = 
-        open System
-        open System.Reflection
-
-        [<NoEquality; NoComparison>]
-        type TypeInfo =
-          | TupleType of Type list
-          | FunctionType of Type * Type
-          | RecordType of (string * Type) list
-          | SumType of (string * (string * Type) list) list
-          | UnitType
-          | ObjectType of Type
-
-             
-        let isNamedType(typ:Type) = not (typ.IsArray || typ.IsByRef || typ.IsPointer)
-        let equivHeadTypes (ty1:Type) (ty2:Type) = 
-            isNamedType(ty1) &&
-            if ty1.IsGenericType then 
-              ty2.IsGenericType && (ty1.GetGenericTypeDefinition()).Equals(ty2.GetGenericTypeDefinition())
-            else 
-              ty1.Equals(ty2)
-
-        let option = typedefof<obj option>
-        let func = typedefof<(obj -> obj)>
-
-        let isOptionType typ = equivHeadTypes typ (typeof<int option>)
-        let isUnitType typ = equivHeadTypes typ (typeof<unit>)
-        let isListType typ = 
-            FSharpType.IsUnion typ && 
-            (let cases = FSharpType.GetUnionCases typ 
-             cases.Length > 0 && equivHeadTypes (typedefof<list<_>>) cases.[0].DeclaringType)
-
-        module Type =
-
-            let recdDescOfProps props = 
-               props |> Array.toList |> List.map (fun (p:PropertyInfo) -> p.Name, p.PropertyType) 
-
-            let getTypeInfoOfType (bindingFlags:BindingFlags) (typ:Type) = 
-                if FSharpType.IsTuple(typ)  then TypeInfo.TupleType (FSharpType.GetTupleElements(typ) |> Array.toList)
-                elif FSharpType.IsFunction(typ) then let ty1,ty2 = FSharpType.GetFunctionElements typ in  TypeInfo.FunctionType( ty1,ty2)
-                elif FSharpType.IsUnion(typ,bindingFlags) then 
-                    let cases = FSharpType.GetUnionCases(typ,bindingFlags) 
-                    match cases with 
-                    | [| |] -> TypeInfo.ObjectType(typ) 
-                    | _ -> 
-                        TypeInfo.SumType(cases |> Array.toList |> List.map (fun case -> 
-                            let flds = case.GetFields()
-                            case.Name,recdDescOfProps(flds)))
-                elif FSharpType.IsRecord(typ,bindingFlags) then 
-                    let flds = FSharpType.GetRecordFields(typ,bindingFlags) 
-                    TypeInfo.RecordType(recdDescOfProps(flds))
-                else
-                    TypeInfo.ObjectType(typ)
-
-            let IsOptionType (typ:Type) = isOptionType typ
-            let IsListType (typ:Type) = isListType typ
-            let IsUnitType (typ:Type) = isUnitType typ
-
-        [<NoEquality; NoComparison>]
-        type ValueInfo =
-          | TupleValue of obj list
-          | FunctionClosureValue of System.Type 
-          | RecordValue of (string * obj) list
-          | ConstructorValue of string * (string * obj) list
-          | ExceptionValue of System.Type * (string * obj) list
-          | UnitValue
-          | ObjectValue of obj
-
-        module Value = 
-       
-            // Analyze an object to see if it the representation
-            // of an F# value.
-            let GetValueInfoOfObject (bindingFlags:BindingFlags) (obj : obj) = 
-              match obj with 
-              | null -> ObjectValue(obj)
-              | _ -> 
-                let reprty = obj.GetType() 
-
-                // First a bunch of special rules for tuples
-                // Because of the way F# currently compiles tuple values 
-                // of size > 7 we can only reliably reflect on sizes up
-                // to 7.
-
-                if FSharpType.IsTuple reprty then 
-                    TupleValue (FSharpValue.GetTupleFields obj |> Array.toList)
-                elif FSharpType.IsFunction reprty then 
-                    FunctionClosureValue reprty
-                    
-                // It must be exception, abstract, record or union.
-                // Either way we assume the only properties defined on
-                // the type are the actual fields of the type.  Again,
-                // we should be reading attributes here that indicate the
-                // true structure of the type, e.g. the order of the fields.   
-                elif FSharpType.IsUnion(reprty,bindingFlags) then 
-                    let tag,vals = FSharpValue.GetUnionFields (obj,reprty,bindingFlags) 
-                    let props = tag.GetFields()
-                    let pvals = (props,vals) ||> Array.map2 (fun prop v -> prop.Name,v)
-                    ConstructorValue(tag.Name, Array.toList pvals)
-
-                elif FSharpType.IsExceptionRepresentation(reprty,bindingFlags) then 
-                    let props = FSharpType.GetExceptionFields(reprty,bindingFlags) 
-                    let vals = FSharpValue.GetExceptionFields(obj,bindingFlags) 
-                    let pvals = (props,vals) ||> Array.map2 (fun prop v -> prop.Name,v)
-                    ExceptionValue(reprty, pvals |> Array.toList)
-
-                elif FSharpType.IsRecord(reprty,bindingFlags) then 
-                    let props = FSharpType.GetRecordFields(reprty,bindingFlags) 
-                    RecordValue(props |> Array.map (fun prop -> prop.Name, prop.GetValue(obj,null)) |> Array.toList)
-                else
-                    ObjectValue(obj)
-
-            // This one is like the above but can make use of additional
-            // statically-known type information to aid in the
-            // analysis of null values. 
-
-            let GetValueInfo bindingFlags (x : 'a)  (* x could be null *) = 
-                let obj = (box x)
-                match obj with 
-                | null -> 
-                   let typ = typeof<'a>
-                   if isOptionType typ then  ConstructorValue("None", [])
-                   elif isUnitType typ then  UnitValue
-                   else ObjectValue(obj)
-                | _ -> 
-                  GetValueInfoOfObject bindingFlags (obj) 
-
-
-            let GetInfo bindingFlags (v:'a) = GetValueInfo bindingFlags (v:'a)
-
-    [<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
-    module Display = 
-
-        open ReflectUtils
-        open LayoutOps
-        let string_of_int (i:int) = i.ToString()
-
-        let typeUsesSystemObjectToString (typ:System.Type) =
-            try let methInfo = typ.GetMethod("ToString",BindingFlags.Public ||| BindingFlags.Instance,null,[| |],null)
-                methInfo.DeclaringType = typeof<System.Object>
-            with e -> false
-
-        /// If "str" ends with "ending" then remove it from "str", otherwise no change.
-        let trimEnding (ending:string) (str:string) =
-#if FX_NO_CULTURE_INFO_ARGS
-          if str.EndsWith(ending) then 
-#else
-          if str.EndsWith(ending,StringComparison.Ordinal) then 
-#endif
-              str.Substring(0,str.Length - ending.Length) 
-          else str
-
-        let catchExn f = try Choice1Of2 (f ()) with e -> Choice2Of2 e
-        
-        // An implementation of break stack.
-        // Uses mutable state, relying on linear threading of the state.
-
-        [<NoEquality; NoComparison>]
-        type Breaks = 
-            Breaks of
-                int *     // pos of next free slot 
-                int *     // pos of next possible "outer" break - OR - outer=next if none possible 
-                int array // stack of savings, -ve means it has been broken   
-
-        // next  is next slot to push into - aka size of current occupied stack.  
-        // outer counts up from 0, and is next slot to break if break forced.
-        // - if all breaks forced, then outer=next.
-        // - popping under these conditions needs to reduce outer and next.
-        
-
-        //let dumpBreaks prefix (Breaks(next,outer,stack)) = ()
-        //   printf "%s: next=%d outer=%d stack.Length=%d\n" prefix next outer stack.Length;
-        //   stdout.Flush() 
-             
-        let chunkN = 400      
-        let breaks0 () = Breaks(0,0,Array.create chunkN 0)
-
-        let pushBreak saving (Breaks(next,outer,stack)) =
-            //dumpBreaks "pushBreak" (next,outer,stack);
-            let stack = 
-                if next = stack.Length then
-                  Array.init (next + chunkN) (fun i -> if i < next then stack.[i] else 0) // expand if full 
-                else
-                  stack
-           
-            stack.[next] <- saving;
-            Breaks(next+1,outer,stack)
-
-        let popBreak (Breaks(next,outer,stack)) =
-            //dumpBreaks "popBreak" (next,outer,stack);
-            if next=0 then raise (Failure "popBreak: underflow");
-            let topBroke = stack.[next-1] < 0
-            let outer = if outer=next then outer-1 else outer  // if all broken, unwind 
-            let next  = next - 1
-            Breaks(next,outer,stack),topBroke
-
-        let forceBreak (Breaks(next,outer,stack)) =
-            //dumpBreaks "forceBreak" (next,outer,stack);
-            if outer=next then
-              // all broken 
-                None
-            else
-                let saving = stack.[outer]
-                stack.[outer] <- -stack.[outer];    
-                let outer = outer+1
-                Some (Breaks(next,outer,stack),saving)
-
-        // -------------------------------------------------------------------------
-        // fitting
-        // ------------------------------------------------------------------------
-          
-        let squashTo (maxWidth,leafFormatter) layout =
-            if maxWidth <= 0 then layout else 
-            let rec fit breaks (pos,layout) =
-                // breaks = break context, can force to get indentation savings.
-                // pos    = current position in line
-                // layout = to fit
-                //------
-                // returns:
-                // breaks
-                // layout - with breaks put in to fit it.
-                // pos    - current pos in line = rightmost position of last line of block.
-                // offset - width of last line of block
-                // NOTE: offset <= pos -- depending on tabbing of last block
-               
-                let breaks,layout,pos,offset =
-                    match layout with
-                    | Attr (tag,attrs,l) ->
-                        let breaks,layout,pos,offset = fit breaks (pos,l) 
-                        let layout = Attr (tag,attrs,layout) 
-                        breaks,layout,pos,offset
-                    | Leaf (jl,obj,jr) ->
-                        let text:string = leafFormatter obj 
-                        // save the formatted text from the squash
-                        let layout = Leaf(jl,(text :> obj),jr) 
-                        let textWidth = text.Length
-                        let rec fitLeaf breaks pos =
-                          if pos + textWidth <= maxWidth then
-                              breaks,layout,pos + textWidth,textWidth // great, it fits 
-                          else
-                              match forceBreak breaks with
-                              | None                 -> 
-                                  breaks,layout,pos + textWidth,textWidth // tough, no more breaks 
-                              | Some (breaks,saving) -> 
-                                  let pos = pos - saving 
-                                  fitLeaf breaks pos
-                       
-                        fitLeaf breaks pos
-                    | Node (jl,l,jm,r,jr,joint) ->
-                        let mid = if jm then 0 else 1
-                        match joint with
-                        | Unbreakable    ->
-                            let breaks,l,pos,offsetl = fit breaks (pos,l)    // fit left 
-                            let pos = pos + mid                              // fit space if juxt says so 
-                            let breaks,r,pos,offsetr = fit breaks (pos,r)    // fit right 
-                            breaks,Node (jl,l,jm,r,jr,Unbreakable),pos,offsetl + mid + offsetr
-                        | Broken indent ->
-                            let breaks,l,pos,offsetl = fit breaks (pos,l)    // fit left 
-                            let pos = pos - offsetl + indent                 // broken so - offset left + ident 
-                            let breaks,r,pos,offsetr = fit breaks (pos,r)    // fit right 
-                            breaks,Node (jl,l,jm,r,jr,Broken indent),pos,indent + offsetr
-                        | Breakable indent ->
-                            let breaks,l,pos,offsetl = fit breaks (pos,l)    // fit left 
-                            // have a break possibility, with saving 
-                            let saving = offsetl + mid - indent
-                            let pos = pos + mid
-                            if saving>0 then
-                                let breaks = pushBreak saving breaks
-                                let breaks,r,pos,offsetr = fit breaks (pos,r)
-                                let breaks,broken = popBreak breaks
-                                if broken then
-                                    breaks,Node (jl,l,jm,r,jr,Broken indent)   ,pos,indent + offsetr
-                                else
-                                    breaks,Node (jl,l,jm,r,jr,Breakable indent),pos,offsetl + mid + offsetr
-                            else
-                                // actually no saving so no break 
-                                let breaks,r,pos,offsetr = fit breaks (pos,r)
-                                breaks,Node (jl,l,jm,r,jr,Breakable indent)  ,pos,offsetl + mid + offsetr
-               
-               //Printf.printf "\nDone:     pos=%d offset=%d" pos offset;
-                breaks,layout,pos,offset
-           
-            let breaks = breaks0 ()
-            let pos = 0
-            let _,layout,_,_ = fit breaks (pos,layout)
-            layout
-
-        // -------------------------------------------------------------------------
-        // showL
-        // ------------------------------------------------------------------------
-
-        let combine strs = System.String.Concat(Array.ofList(strs) : string[])
-        let showL opts leafFormatter layout =
-            let push x rstrs = x::rstrs
-            let z0 = [],0
-            let addText (rstrs,i) (text:string) = push text rstrs,i + text.Length
-            let index   (_,i)               = i
-            let extract rstrs = combine(List.rev rstrs) 
-            let newLine (rstrs,_) n     = // \n then spaces... 
-                let indent = new System.String(' ', n)
-                let rstrs = push System.Environment.NewLine rstrs
-                let rstrs = push indent rstrs
-                rstrs,n
-
-            // addL: pos is tab level 
-            let rec addL z pos layout = 
-                match layout with 
-                | Leaf (_,obj,_)                 -> 
-                    let text = leafFormatter obj 
-                    addText z text
-                | Node (_,l,_,r,_,Broken indent) 
-                     // Print width = 0 implies 1D layout, no squash
-                     when not (opts.PrintWidth = 0)  -> 
-                    let z = addL z pos l
-                    let z = newLine z (pos+indent)
-                    let z = addL z (pos+indent) r
-                    z
-                | Node (_,l,jm,r,_,_)             -> 
-                    let z = addL z pos l
-                    let z = if jm then z else addText z " "
-                    let pos = index z
-                    let z = addL z pos r
-                    z
-                | Attr (_,_,l) ->
-                    addL z pos l
-           
-            let rstrs,_ = addL z0 0 layout
-            extract rstrs
-
-
-        // -------------------------------------------------------------------------
-        // outL
-        // ------------------------------------------------------------------------
-
-        let outL outAttribute leafFormatter (chan : TextWriter) layout =
-            // write layout to output chan directly 
-            let write (s:string) = chan.Write(s)
-            // z is just current indent 
-            let z0 = 0
-            let index i = i
-            let addText z text  = write text;  (z + text.Length)
-            let newLine _ n     = // \n then spaces... 
-                let indent = new System.String(' ',n)
-                chan.WriteLine();
-                write indent;
-                n
-                
-            // addL: pos is tab level 
-            let rec addL z pos layout = 
-                match layout with 
-                | Leaf (_,obj,_)                 -> 
-                    let text = leafFormatter obj 
-                    addText z text
-                | Node (_,l,_,r,_,Broken indent) -> 
-                    let z = addL z pos l
-                    let z = newLine z (pos+indent)
-                    let z = addL z (pos+indent) r
-                    z
-                | Node (_,l,jm,r,_,_)             -> 
-                    let z = addL z pos l
-                    let z = if jm then z else addText z " "
-                    let pos = index z
-                    let z = addL z pos r
-                    z 
-                | Attr (tag,attrs,l) ->
-                let _ = outAttribute tag attrs true
-                let z = addL z pos l
-                let _ = outAttribute tag attrs false
-                z
-           
-            let _ = addL z0 0 layout
-            ()
-
-        // --------------------------------------------------------------------
-        // pprinter: using general-purpose reflection...
-        // -------------------------------------------------------------------- 
-          
-        let getValueInfo bindingFlags (x:'a) = Value.GetInfo bindingFlags (x:'a)
-
-        let unpackCons recd =
-            match recd with 
-            | [(_,h);(_,t)] -> (h,t)
-            | _             -> failwith "unpackCons"
-
-        let getListValueInfo bindingFlags (x:obj) =
-            match x with 
-            | null -> None 
-            | _ -> 
-                match getValueInfo bindingFlags x with
-                | ConstructorValue ("Cons",recd) -> Some (unpackCons recd)
-                | ConstructorValue ("Empty",[]) -> None
-                | _ -> failwith "List value had unexpected ValueInfo"
-
-        let compactCommaListL xs = sepListL (sepL ",") xs // compact, no spaces around "," 
-        let nullL = wordL "null"
-        let measureL = wordL "()"
-          
-        // --------------------------------------------------------------------
-        // pprinter: attributes
-        // -------------------------------------------------------------------- 
-
-        let makeRecordVerticalL nameXs =
-            let itemL (name,xL) = let labelL = wordL name in ((labelL ^^ wordL "=")) -- (xL  ^^ (rightL ";"))
-            let braceL xs = (leftL "{") ^^ xs ^^ (rightL "}")
-            braceL (aboveListL (List.map itemL nameXs))
-
-        let makeRecordHorizontalL nameXs = (* This is a more compact rendering of records - and is more like tuples *)
-            let itemL (name,xL) = let labelL = wordL name in ((labelL ^^ wordL "=")) -- xL
-            let braceL xs = (leftL "{") ^^ xs ^^ (rightL "}")
-            braceL (sepListL (rightL ";")  (List.map itemL nameXs))
-
-        let makeRecordL nameXs = makeRecordVerticalL nameXs (* REVIEW: switch to makeRecordHorizontalL ? *)
-
-        let makePropertiesL nameXs =
-            let itemL (name,v) = 
-               let labelL = wordL name 
-               (labelL ^^ wordL "=")
-               ^^ (match v with 
-                   | None -> wordL "?" 
-                   | Some xL -> xL)
-               ^^ (rightL ";")
-            let braceL xs = (leftL "{") ^^ xs ^^ (rightL "}")
-            braceL (aboveListL (List.map itemL nameXs))
-
-        let makeListL itemLs =
-            (leftL "[") 
-            ^^ sepListL (rightL ";") itemLs 
-            ^^ (rightL "]")
-
-        let makeArrayL xs =
-            (leftL "[|") 
-            ^^ sepListL (rightL ";") xs 
-            ^^ (rightL "|]")
-
-        let makeArray2L xs = leftL "[" ^^ aboveListL xs ^^ rightL "]"  
-
-        // --------------------------------------------------------------------
-        // pprinter: anyL - support functions
-        // -------------------------------------------------------------------- 
-
-        let getProperty (obj: obj) name =
-            let ty = obj.GetType()
-#if FX_NO_CULTURE_INFO_ARGS
-            ty.InvokeMember(name, (BindingFlags.GetProperty ||| BindingFlags.Instance ||| BindingFlags.Public ||| BindingFlags.NonPublic), null, obj, [| |])
-#else
-            ty.InvokeMember(name, (BindingFlags.GetProperty ||| BindingFlags.Instance ||| BindingFlags.Public ||| BindingFlags.NonPublic), null, obj, [| |],CultureInfo.InvariantCulture)
-#endif
-
-        let formatChar isChar c = 
-            match c with 
-            | '\'' when isChar -> "\\\'"
-            | '\"' when not isChar -> "\\\""
-            //| '\n' -> "\\n"
-            //| '\r' -> "\\r"
-            //| '\t' -> "\\t"
-            | '\\' -> "\\\\"
-            | '\b' -> "\\b"
-            | _ when System.Char.IsControl(c) -> 
-                 let d1 = (int c / 100) % 10 
-                 let d2 = (int c / 10) % 10 
-                 let d3 = int c % 10 
-                 "\\" + d1.ToString() + d2.ToString() + d3.ToString()
-            | _ -> c.ToString()
-            
-        let formatString (s:string) =
-            let rec check i = i < s.Length && not (System.Char.IsControl(s,i)) && s.[i] <> '\"' && check (i+1) 
-            let rec conv i acc = if i = s.Length then combine (List.rev acc) else conv (i+1) (formatChar false s.[i] :: acc)  
-            "\"" + s + "\""
-            // REVIEW: should we check for the common case of no control characters? Reinstate the following?
-            //"\"" + (if check 0 then s else conv 0 []) + "\""
-
-        let formatStringInWidth (width:int) (str:string) =
-            // Return a truncated version of the string, e.g.
-            //   "This is the initial text, which has been truncat"+[12 chars]
-            //
-            // Note: The layout code forces breaks based on leaf size and possible break points.
-            //       It does not force leaf size based on width.
-            //       So long leaf-string width can not depend on their printing context...
-            //
-            // The suffix like "+[dd chars]" is 11 chars.
-            //                  12345678901
-            let suffixLength    = 11 // turning point suffix length
-            let prefixMinLength = 12 // arbitrary. If print width is reduced, want to print a minimum of information on strings...
-            let prefixLength = max (width - 2 (*quotes*) - suffixLength) prefixMinLength
-            "\"" + (str.Substring(0,prefixLength)) + "\"" + "+[" + (str.Length - prefixLength).ToString() + " chars]"
-
-        // --------------------------------------------------------------------
-        // pprinter: anyL
-        // -------------------------------------------------------------------- 
-                           
-        type Precedence = 
-            | BracketIfTupleOrNotAtomic = 2
-            | BracketIfTuple = 3
-            | NeverBracket = 4
-
-        // In fsi.exe, certain objects are not printed for top-level bindings.
-        [<StructuralEquality; NoComparison>]
-        type ShowMode = 
-            | ShowAll 
-            | ShowTopLevelBinding
-
-        // polymorphic and inner recursion limitations prevent us defining polyL in the recursive loop 
-        let polyL bindingFlags (objL: ShowMode -> int -> Precedence -> ValueInfo -> obj -> Layout) showMode i prec  (x:'a) (* x could be null *) =
-            objL showMode i prec (getValueInfo bindingFlags (x:'a))  (box x) 
-
-        let anyL showMode bindingFlags (opts:FormatOptions) (x:'a) =
-            // showMode = ShowTopLevelBinding on the outermost expression when called from fsi.exe,
-            // This allows certain outputs, e.g. objects that would print as <seq> to be suppressed, etc. See 4343.
-            // Calls to layout proper sub-objects should pass showMode = ShowAll.
-
-            // Precedences to ensure we add brackets in the right places
-            
-            // Keep a record of objects encountered along the way
-            let path = Dictionary<obj,int>(10,HashIdentity.Reference)
-
-            // Roughly count the "nodes" printed, e.g. leaf items and inner nodes, but not every bracket and comma.
-            let size = ref opts.PrintSize
-            let exceededPrintSize() = !size<=0
-            let countNodes n = if !size > 0 then size := !size - n else () (* no need to keep decrementing (and avoid wrap around) *)
-            let stopShort _ = exceededPrintSize() // for unfoldL
-
-            // Recursive descent
-            let rec objL depthLim prec (x:obj) = polyL bindingFlags objWithReprL ShowAll  depthLim prec x (* showMode for inner expr *)
-            and sameObjL depthLim prec (x:obj) = polyL bindingFlags objWithReprL showMode depthLim prec x (* showMode preserved *)
-
-            and objWithReprL showMode depthLim prec (info:ValueInfo) (x:obj) (* x could be null *) =
-                try
-                  if depthLim<=0 || exceededPrintSize() then wordL "..." else
-                  match x with 
-                  | null -> 
-                    reprL showMode (depthLim-1) prec info x
-                  | _    ->
-                    if (path.ContainsKey(x)) then 
-                       wordL "..."
-                    else 
-                        path.Add(x,0);
-                        let res = 
-                          // Lazy<T> values. VS2008 used StructuredFormatDisplayAttribute to show via ToString. Dev10 (no attr) needs a special case.
-                          let ty = x.GetType()
-                          if ty.IsGenericType && ty.GetGenericTypeDefinition() = typedefof<Lazy<_>> then
-                            Some (wordL (x.ToString()))
-                          else
-                            // Try the StructuredFormatDisplayAttribute extensibility attribute
-                            match x.GetType().GetCustomAttributes (typeof<StructuredFormatDisplayAttribute>, true) with
-                            | null | [| |] -> None
-                            | res -> 
-                               let attr = (res.[0] :?> StructuredFormatDisplayAttribute) 
-                               let txt = attr.Value
-                               if txt = null || txt.Length <= 1 then  
-                                   None
-                               else
-                                  let p1 = txt.IndexOf ("{", StringComparison.Ordinal)
-                                  let p2 = txt.LastIndexOf ("}", StringComparison.Ordinal)
-                                  if p1 < 0 || p2 < 0 || p1+1 >= p2 then 
-                                      None 
-                                  else
-                                      let preText = if p1 <= 0 then "" else txt.[0..p1-1]
-                                      let postText = if p2+1 >= txt.Length then "" else txt.[p2+1..]
-                                      let prop = txt.[p1+1..p2-1]
-                                      match catchExn (fun () -> getProperty x prop) with
-                                        | Choice2Of2 e -> Some (wordL ("<StructuredFormatDisplay exception: " + e.Message + ">"))
-                                        | Choice1Of2 alternativeObj ->
-                                            try 
-                                                let alternativeObjL = 
-                                                  match alternativeObj with 
-                                                      // A particular rule is that if the alternative property
-                                                      // returns a string, we turn off auto-quoting and esaping of
-                                                      // the string, i.e. just treat the string as display text.
-                                                      // This allows simple implementations of 
-                                                      // such as
-                                                      //
-                                                      //    [<StructuredFormatDisplay("{StructuredDisplayString}I")>]
-                                                      //    type BigInt(signInt:int, v : BigNat) =
-                                                      //        member x.StructuredDisplayString = x.ToString()
-                                                      //
-                                                      | :? string as s -> sepL s
-                                                      | _ -> sameObjL (depthLim-1) Precedence.BracketIfTuple alternativeObj
-                                                countNodes 0 (* 0 means we do not count the preText and postText *)
-                                                Some (leftL preText ^^ alternativeObjL ^^ rightL postText)
-                                            with _ -> 
-                                              None
-
-                        let res = 
-                            match res with 
-                            | Some res -> res
-                            | None     -> reprL showMode (depthLim-1) prec info x
-                        path .Remove(x) |> ignore;
-                        res
-                with
-                  e ->
-                    countNodes 1
-                    wordL ("Error: " + e.Message)
-
-            and recdAtomicTupleL depthLim recd =
-                // tuples up args to UnionConstruction or ExceptionConstructor. no node count.
-                match recd with 
-                | [(_,x)] -> objL depthLim Precedence.BracketIfTupleOrNotAtomic x 
-                | txs     -> leftL "(" ^^ compactCommaListL (List.map (snd >> objL depthLim Precedence.BracketIfTuple) txs) ^^ rightL ")" 
-
-            and bracketIfL b basicL =
-                if b then (leftL "(") ^^ basicL ^^ (rightL ")") else basicL
-
-            and reprL showMode depthLim prec repr x (* x could be null *) =
-                let showModeFilter lay = match showMode with ShowAll -> lay | ShowTopLevelBinding -> emptyL                                                             
-                match repr with 
-                | TupleValue vals -> 
-                    let basicL = sepListL (rightL ",") (List.map (objL depthLim Precedence.BracketIfTuple ) vals)
-                    bracketIfL (prec <= Precedence.BracketIfTuple) basicL 
-
-                | RecordValue items -> 
-                    let itemL (name,x) =
-                      countNodes 1 // record labels are counted as nodes. [REVIEW: discussion under 4090].
-                      (name,objL depthLim Precedence.BracketIfTuple x)
-                    makeRecordL (List.map itemL items)
-
-                | ConstructorValue (constr,recd) when (* x is List<T>. Note: "null" is never a valid list value. *)
-                                                      x<>null && Type.IsListType (x.GetType()) ->
-                    match constr with 
-                    | "Cons" -> 
-                        let (x,xs) = unpackCons recd
-                        let project xs = getListValueInfo bindingFlags xs
-                        let itemLs = objL depthLim Precedence.BracketIfTuple x :: boundedUnfoldL (objL depthLim Precedence.BracketIfTuple) project stopShort xs (opts.PrintLength - 1)
-                        makeListL itemLs
-                    | _ ->
-                        countNodes 1
-                        wordL "[]" 
-
-                | ConstructorValue(nm,[])   ->
-                    countNodes 1
-                    (wordL nm)
-
-                | ConstructorValue(nm,recd) ->
-                    countNodes 1 (* e.g. Some (Some (Some (Some 2))) should count for 5 *)
-                    (wordL nm --- recdAtomicTupleL depthLim recd) |> bracketIfL (prec <= Precedence.BracketIfTupleOrNotAtomic)
-
-                | ExceptionValue(ty,recd) ->
-                    countNodes 1
-                    let name = ty.Name 
-                    match recd with
-                      | []   -> (wordL name)
-                      | recd -> (wordL name --- recdAtomicTupleL depthLim recd) |> bracketIfL (prec <= Precedence.BracketIfTupleOrNotAtomic)
-
-                | FunctionClosureValue ty ->
-                    // Q: should function printing include the ty.Name? It does not convey much useful info to most users, e.g. "clo@0_123".    
-                    countNodes 1
-                    wordL ("<fun:"+ty.Name+">") |> showModeFilter
-
-                | ObjectValue(obj)  ->
-                    match obj with 
-                    | null -> (countNodes 1; nullL)
-                    | _ -> 
-                    let ty = obj.GetType()
-                    match obj with 
-                    | :? string as s ->
-                        countNodes 1
-                        wordL (formatString s)  
-                    | :? System.Array as arr -> 
-                        match arr.Rank with
-                        | 1 -> 
-                             let n = arr.Length
-                             let b1 = arr.GetLowerBound(0) 
-                             let project depthLim = if depthLim=(b1+n) then None else Some (box (arr.GetValue(depthLim)),depthLim+1)
-                             let itemLs = boundedUnfoldL (objL depthLim Precedence.BracketIfTuple) project stopShort b1 opts.PrintLength
-                             makeArrayL (if b1 = 0 then itemLs else wordL("bound1="+string_of_int b1)::itemLs)
-                        | 2 -> 
-                             let n1 = arr.GetLength(0)
-                             let n2 = arr.GetLength(1)
-                             let b1 = arr.GetLowerBound(0) 
-                             let b2 = arr.GetLowerBound(1) 
-                             let project2 x y =
-                               if x>=(b1+n1) || y>=(b2+n2) then None
-                               else Some (box (arr.GetValue(x,y)),y+1)
-                             let rowL x = boundedUnfoldL (objL depthLim Precedence.BracketIfTuple) (project2 x) stopShort b2 opts.PrintLength |> makeListL
-                             let project1 x = if x>=(b1+n1) then None else Some (x,x+1)
-                             let rowsL  = boundedUnfoldL rowL project1 stopShort b1 opts.PrintLength
-                             makeArray2L (if b1=0 && b2 = 0 then rowsL else wordL("bound1=" + string_of_int b1)::wordL("bound2=" + string_of_int b2)::rowsL)
-                          | n -> 
-                             makeArrayL [wordL("rank=" + string_of_int n)]
-                        
-                    // Format 'set' and 'map' nicely
-                    | _ when  
-                          (let ty = obj.GetType()
-                           ty.IsGenericType && (ty.GetGenericTypeDefinition() = typedefof<Map<int,int>> 
-                                                || ty.GetGenericTypeDefinition() = typedefof<Set<int>>) ) ->
-                         let ty = obj.GetType()
-                         let word = if ty.GetGenericTypeDefinition() = typedefof<Map<int,int>> then "map" else "set"
-                         let possibleKeyValueL v = 
-                             if word = "map" &&
-                                (match v with null -> false | _ -> true) && 
-                                v.GetType().IsGenericType && 
-                                v.GetType().GetGenericTypeDefinition() = typedefof<KeyValuePair<int,int>> then
-                                  objL depthLim Precedence.BracketIfTuple (v.GetType().GetProperty("Key").GetValue(v, [| |]), 
-                                                                           v.GetType().GetProperty("Value").GetValue(v, [| |]))
-                             else
-                                  objL depthLim Precedence.BracketIfTuple v
-                         let it = (obj :?>  System.Collections.IEnumerable).GetEnumerator() 
-                         try 
-                           let itemLs = boundedUnfoldL possibleKeyValueL (fun () -> if it.MoveNext() then Some(it.Current,()) else None) stopShort () (1+opts.PrintLength/12)
-                           (wordL word --- makeListL itemLs) |> bracketIfL (prec <= Precedence.BracketIfTupleOrNotAtomic)
-                         finally 
-                            match it with 
-                            | :? System.IDisposable as e -> e.Dispose()
-                            | _ -> ()
-
-                    | :? System.Collections.IEnumerable as ie ->
-                         if opts.ShowIEnumerable then
-                           let word = "seq"
-                           let it = ie.GetEnumerator() 
-                           try 
-                             let itemLs = boundedUnfoldL (objL depthLim Precedence.BracketIfTuple) (fun () -> if it.MoveNext() then Some(it.Current,()) else None) stopShort () (1+opts.PrintLength/30)
-                             (wordL word --- makeListL itemLs) |> bracketIfL (prec <= Precedence.BracketIfTupleOrNotAtomic)
-                           finally 
-                              match it with 
-                              | :? System.IDisposable as e -> e.Dispose()
-                              | _ -> ()
-                             
-                         else
-                           // Sequence printing is turned off for declared-values, and maybe be disabled to users.
-                           // There is choice here, what to print? <seq> or ... or ?
-                           // Also, in the declared values case, if the sequence is actually a known non-lazy type (list, array etc etc) we could print it.  
-                           wordL "<seq>" |> showModeFilter
-                    | _ ->
-                         if showMode = ShowTopLevelBinding && typeUsesSystemObjectToString (obj.GetType()) then
-                           emptyL
-                         else
-                           countNodes 1
-                           let basicL = LayoutOps.objL obj  // This buries an obj in the layout, rendered at squash time via a leafFormatter.
-                                                            // If the leafFormatter was directly here, then layout leaves could store strings.
-                           match obj with 
-                           | _ when opts.ShowProperties ->
-                              let props = ty.GetProperties(BindingFlags.GetField ||| BindingFlags.Instance ||| BindingFlags.Public)
-                              // massively reign in deep printing of properties 
-                              let nDepth = depthLim/10
-                              System.Array.Sort((props:>System.Array),{ new System.Collections.IComparer with member this.Compare(p1,p2) = compare ((p1 :?> PropertyInfo).Name) ((p2 :?> PropertyInfo).Name) } );
-                              if props.Length = 0 || (nDepth <= 0) then basicL 
-                              else basicL --- 
-                                     (props 
-                                      |> Array.toList 
-                                      |> List.map (fun p -> (p.Name,(try Some (objL nDepth Precedence.BracketIfTuple (getProperty obj p.Name)) 
-                                                                     with _ -> None)))
-                                      |> makePropertiesL)
-                           | _ -> basicL 
-                | UnitValue -> countNodes 1; measureL
-
-            polyL bindingFlags objWithReprL showMode opts.PrintDepth Precedence.BracketIfTuple x
-
-        // --------------------------------------------------------------------
-        // pprinter: leafFormatter
-        // --------------------------------------------------------------------
-
-#if Suggestion4299
-        // See bug 4299. Suppress FSI_dddd+<etc> from fsi printer.
-        let fixupForInteractiveFSharpClassesWithNoToString obj (text:string) =
-              // Given obj:T.
-              // If T is a nested type inside a parent type called FSI_dddd, then it looks like an F# Interactive type.
-              // Further, if the .ToString() text starts with "FSI_dddd+T" then it looks like it's the default ToString.
-              // A better test: it is default ToString if the MethodInfo.DeclaringType is System.Object.
-              // In this case, replace "FSI_dddd+T" by "T".
-              // assert(obj <> null)
-              let fullName = obj.GetType().FullName // e.g. "FSI_0123+Name"
-              let name     = obj.GetType().Name     // e.g. "Name"
-              let T = obj.GetType()      
-              if text.StartsWith(fullName) then
-                  // text could be a default .ToString() since it starts with the FullName of the type. More checks...
-                  if T.IsNested &&
-                     T.DeclaringType.Name.StartsWith("FSI_") &&                             // Name has "FSI_" which is 
-                     T.DeclaringType.Name.Substring(4) |> Seq.forall System.Char.IsDigit    // followed by digits?
-                  then
-                      name ^ text.Substring(fullName.Length)    // replace fullName by name at start of text
-                  else
-                      text
-              else
-                text
-#endif
-
-        let leafFormatter (opts:FormatOptions) (obj :obj) =
-            match obj with 
-            | null -> "null"
-            | :? double as d -> 
-                let s = d.ToString(opts.FloatingPointFormat,opts.FormatProvider)
-                if System.Double.IsNaN(d) then "nan"
-                elif System.Double.IsNegativeInfinity(d) then "-infinity"
-                elif System.Double.IsPositiveInfinity(d) then "infinity"
-                elif opts.FloatingPointFormat.[0] = 'g'  && String.forall(fun c -> System.Char.IsDigit(c) || c = '-')  s
-                then s + ".0" 
-                else s
-            | :? single as d -> 
-                (if System.Single.IsNaN(d) then "nan"
-                 elif System.Single.IsNegativeInfinity(d) then "-infinity"
-                 elif System.Single.IsPositiveInfinity(d) then "infinity"
-                 elif opts.FloatingPointFormat.Length >= 1 && opts.FloatingPointFormat.[0] = 'g' 
-                  && float32(System.Int32.MinValue) < d && d < float32(System.Int32.MaxValue) 
-                  && float32(int32(d)) = d 
-                 then (System.Convert.ToInt32 d).ToString(opts.FormatProvider) + ".0"
-                 else d.ToString(opts.FloatingPointFormat,opts.FormatProvider)) 
-                + "f"
-            | :? System.Decimal as d -> d.ToString("g",opts.FormatProvider) + "M"
-            | :? uint64 as d -> d.ToString(opts.FormatProvider) + "UL"
-            | :? int64  as d -> d.ToString(opts.FormatProvider) + "L"
-            | :? int32  as d -> d.ToString(opts.FormatProvider)
-            | :? uint32 as d -> d.ToString(opts.FormatProvider) + "u"
-            | :? int16  as d -> d.ToString(opts.FormatProvider) + "s"
-            | :? uint16 as d -> d.ToString(opts.FormatProvider) + "us"
-            | :? sbyte  as d -> d.ToString(opts.FormatProvider) + "y"
-            | :? byte   as d -> d.ToString(opts.FormatProvider) + "uy"
-            | :? nativeint as d -> d.ToString() + "n"
-            | :? unativeint  as d -> d.ToString() + "un"
-            | :? bool   as b -> (if b then "true" else "false")
-            | :? char   as c -> "\'" + formatChar true c + "\'"
-            | _ -> try  let text = obj.ToString()
-                        text
-                   with e ->
-                     // If a .ToString() call throws an exception, catch it and use the message as the result.
-                     // This may be informative, e.g. division by zero etc...
-                     "<ToString exception: " + e.Message + ">" 
-
-        let any_to_layout opts x = anyL ShowAll BindingFlags.Public opts x
-
-        let squash_layout opts l = 
-            // Print width = 0 implies 1D layout, no squash
-            if opts.PrintWidth = 0 then 
-                l 
-            else 
-                l |> squashTo (opts.PrintWidth,leafFormatter opts)
-
-        let output_layout opts oc l = 
-            l |> squash_layout opts 
-              |> outL opts.AttributeProcessor (leafFormatter opts) oc
-
-        let layout_to_string opts l = 
-            l |> squash_layout opts 
-              |> showL opts (leafFormatter opts) 
-
-        let output_any_ex opts oc x = x |> any_to_layout opts |> output_layout opts oc
-
-        let output_any oc x = output_any_ex FormatOptions.Default oc x
-
-        let layout_as_string opts x = x |> any_to_layout opts |> layout_to_string opts
-
-        let any_to_string x = layout_as_string FormatOptions.Default x
-
-
+//=========================================================================
+// (c) Microsoft Corporation 2005-2009. 
+//=========================================================================
+
+#nowarn "52" // The value has been copied to ensure the original is not mutated by this operation
+
+namespace Microsoft.FSharp.Text.StructuredFormat
+
+    // Breakable block layout implementation.
+    // This is a fresh implementation of pre-existing ideas.
+
+    open System
+    open System.Diagnostics
+    open System.Text
+    open System.IO
+    open System.Reflection
+    open System.Globalization
+    open System.Collections.Generic
+    open Microsoft.FSharp.Reflection
+
+    /// A joint, between 2 layouts, is either:
+    ///  - unbreakable, or
+    ///  - breakable, and if broken the second block has a given indentation.
+    [<StructuralEquality; NoComparison>]
+    type Joint =
+     | Unbreakable
+     | Breakable of int
+     | Broken of int
+
+    /// Leaf juxt,data,juxt
+    /// Node juxt,left,juxt,right,juxt and joint
+    ///
+    /// If either juxt flag is true, then no space between words.
+    [<NoEquality; NoComparison>]
+    type Layout =
+     | Leaf of bool * obj * bool
+     | Node of bool * layout * bool * layout * bool * joint
+     | Attr of string * (string * string) list * layout
+
+    and layout = Layout
+
+    and joint = Joint
+
+    [<NoEquality; NoComparison>]
+    type IEnvironment = 
+        abstract GetLayout : obj -> layout
+        abstract MaxColumns : int
+        abstract MaxRows : int
+     
+    [<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+    module LayoutOps = 
+        let rec juxtLeft = function
+          | Leaf (jl,_,_)         -> jl
+          | Node (jl,_,_,_,_,_) -> jl
+          | Attr (_,_,l)        -> juxtLeft l
+
+        let rec juxtRight = function
+          | Leaf (_,_,jr)         -> jr
+          | Node (_,_,_,_,jr,_) -> jr
+          | Attr (_,_,l)        -> juxtRight l
+
+        let mkNode l r joint =
+           let jl = juxtLeft  l 
+           let jm = juxtRight l || juxtLeft r 
+           let jr = juxtRight r 
+           Node(jl,l,jm,r,jr,joint)
+
+
+        // constructors
+
+
+        let objL   (obj:obj) = Leaf (false,obj,false)
+        let sLeaf  (l,(str:string),r) = Leaf (l,(str:>obj),r)
+        let wordL  str = sLeaf (false,str,false)
+        let sepL   str = sLeaf (true ,str,true)   
+        let rightL str = sLeaf (true ,str,false)   
+        let leftL  str = sLeaf (false,str,true)
+        let emptyL = sLeaf (true,"",true)
+        let isEmptyL = function 
+         | Leaf(true,s,true) -> 
+            match s with 
+            | :? string as s -> s = "" 
+            | _ -> false
+         | _ -> false
+         
+
+        let aboveL  l r = mkNode l r (Broken 0)
+
+        let joinN i l r = mkNode l r (Breakable i)                                      
+        let join  = joinN 0
+        let join1 = joinN 1
+        let join2 = joinN 2
+        let join3 = joinN 3
+
+        let tagAttrL tag attrs l = Attr(tag,attrs,l)
+
+        let apply2 f l r = if isEmptyL l then r else
+                           if isEmptyL r then l else f l r
+
+        let (^^)  l r  = mkNode l r (Unbreakable)
+        let (++)  l r  = mkNode l r (Breakable 0)
+        let (--)  l r  = mkNode l r (Breakable 1)
+        let (---) l r  = mkNode l r (Breakable 2)
+        let (@@)   l r = apply2 (fun l r -> mkNode l r (Broken 0)) l r
+        let (@@-)  l r = apply2 (fun l r -> mkNode l r (Broken 1)) l r
+        let (@@--) l r = apply2 (fun l r -> mkNode l r (Broken 2)) l r
+        let tagListL tagger = function
+            | []    -> emptyL
+            | [x]   -> x
+            | x::xs ->
+                let rec process' prefixL = function
+                    []    -> prefixL
+                  | y::ys -> process' ((tagger prefixL) ++ y) ys
+                in  process' x xs
+            
+        let commaListL x = tagListL (fun prefixL -> prefixL ^^ rightL ",") x
+        let semiListL x  = tagListL (fun prefixL -> prefixL ^^ rightL ";") x
+        let spaceListL x = tagListL (fun prefixL -> prefixL) x
+        let sepListL x y = tagListL (fun prefixL -> prefixL ^^ x) y
+        let bracketL l = leftL "(" ^^ l ^^ rightL ")"
+        let tupleL xs = bracketL (sepListL (sepL ",") xs)
+        let aboveListL = function
+          | []    -> emptyL
+          | [x]   -> x
+          | x::ys -> List.fold (fun pre y -> pre @@ y) x ys
+
+        let optionL xL = function
+            None   -> wordL "None"
+          | Some x -> wordL "Some" -- (xL x)
+
+        let listL xL xs = leftL "[" ^^ sepListL (sepL ";") (List.map xL xs) ^^ rightL "]"
+
+        let squareBracketL x = leftL "[" ^^ x ^^ rightL "]"    
+
+        let braceL         x = leftL "{" ^^ x ^^ rightL "}"
+
+        let boundedUnfoldL
+                    (itemL     : 'a -> layout)
+                    (project   : 'z -> ('a * 'z) option)
+                    (stopShort : 'z -> bool)
+                    (z : 'z)
+                    maxLength =
+          let rec consume n z =
+            if stopShort z then [wordL "..."] else
+            match project z with
+              | None       -> []  (* exhaused input *)
+              | Some (x,z) -> if n<=0 then [wordL "..."]               (* hit print_length limit *)
+                                      else itemL x :: consume (n-1) z  (* cons recursive... *)
+          consume maxLength z  
+
+        let unfoldL itemL project z maxLength = boundedUnfoldL  itemL project (fun _ -> false) z maxLength
+          
+    /// These are a typical set of options used to control structured formatting.
+    [<NoEquality; NoComparison>]
+    type FormatOptions = 
+        { FloatingPointFormat: string;
+          AttributeProcessor: (string -> (string * string) list -> bool -> unit);
+          FormatProvider: System.IFormatProvider;
+          BindingFlags: System.Reflection.BindingFlags
+          PrintWidth : int; 
+          PrintDepth : int; 
+          PrintLength : int;
+          PrintSize : int;        
+          ShowProperties : bool;
+          ShowIEnumerable: bool; }
+        static member Default =
+            { FormatProvider = (System.Globalization.CultureInfo.InvariantCulture :> System.IFormatProvider);
+              AttributeProcessor= (fun _ _ _ -> ());
+              BindingFlags = System.Reflection.BindingFlags.Public;
+              FloatingPointFormat = "g10";
+              PrintWidth = 80 ; 
+              PrintDepth = 100 ; 
+              PrintLength = 100;
+              PrintSize = 10000;
+              ShowProperties = false;
+              ShowIEnumerable = true; }
+
+
+
+    module ReflectUtils = 
+        open System
+        open System.Reflection
+
+        [<NoEquality; NoComparison>]
+        type TypeInfo =
+          | TupleType of Type list
+          | FunctionType of Type * Type
+          | RecordType of (string * Type) list
+          | SumType of (string * (string * Type) list) list
+          | UnitType
+          | ObjectType of Type
+
+             
+        let isNamedType(typ:Type) = not (typ.IsArray || typ.IsByRef || typ.IsPointer)
+        let equivHeadTypes (ty1:Type) (ty2:Type) = 
+            isNamedType(ty1) &&
+            if ty1.IsGenericType then 
+              ty2.IsGenericType && (ty1.GetGenericTypeDefinition()).Equals(ty2.GetGenericTypeDefinition())
+            else 
+              ty1.Equals(ty2)
+
+        let option = typedefof<obj option>
+        let func = typedefof<(obj -> obj)>
+
+        let isOptionType typ = equivHeadTypes typ (typeof<int option>)
+        let isUnitType typ = equivHeadTypes typ (typeof<unit>)
+        let isListType typ = 
+            FSharpType.IsUnion typ && 
+            (let cases = FSharpType.GetUnionCases typ 
+             cases.Length > 0 && equivHeadTypes (typedefof<list<_>>) cases.[0].DeclaringType)
+
+        module Type =
+
+            let recdDescOfProps props = 
+               props |> Array.toList |> List.map (fun (p:PropertyInfo) -> p.Name, p.PropertyType) 
+
+            let getTypeInfoOfType (bindingFlags:BindingFlags) (typ:Type) = 
+                if FSharpType.IsTuple(typ)  then TypeInfo.TupleType (FSharpType.GetTupleElements(typ) |> Array.toList)
+                elif FSharpType.IsFunction(typ) then let ty1,ty2 = FSharpType.GetFunctionElements typ in  TypeInfo.FunctionType( ty1,ty2)
+                elif FSharpType.IsUnion(typ,bindingFlags) then 
+                    let cases = FSharpType.GetUnionCases(typ,bindingFlags) 
+                    match cases with 
+                    | [| |] -> TypeInfo.ObjectType(typ) 
+                    | _ -> 
+                        TypeInfo.SumType(cases |> Array.toList |> List.map (fun case -> 
+                            let flds = case.GetFields()
+                            case.Name,recdDescOfProps(flds)))
+                elif FSharpType.IsRecord(typ,bindingFlags) then 
+                    let flds = FSharpType.GetRecordFields(typ,bindingFlags) 
+                    TypeInfo.RecordType(recdDescOfProps(flds))
+                else
+                    TypeInfo.ObjectType(typ)
+
+            let IsOptionType (typ:Type) = isOptionType typ
+            let IsListType (typ:Type) = isListType typ
+            let IsUnitType (typ:Type) = isUnitType typ
+
+        [<NoEquality; NoComparison>]
+        type ValueInfo =
+          | TupleValue of obj list
+          | FunctionClosureValue of System.Type 
+          | RecordValue of (string * obj) list
+          | ConstructorValue of string * (string * obj) list
+          | ExceptionValue of System.Type * (string * obj) list
+          | UnitValue
+          | ObjectValue of obj
+
+        module Value = 
+       
+            // Analyze an object to see if it the representation
+            // of an F# value.
+            let GetValueInfoOfObject (bindingFlags:BindingFlags) (obj : obj) = 
+              match obj with 
+              | null -> ObjectValue(obj)
+              | _ -> 
+                let reprty = obj.GetType() 
+
+                // First a bunch of special rules for tuples
+                // Because of the way F# currently compiles tuple values 
+                // of size > 7 we can only reliably reflect on sizes up
+                // to 7.
+
+                if FSharpType.IsTuple reprty then 
+                    TupleValue (FSharpValue.GetTupleFields obj |> Array.toList)
+                elif FSharpType.IsFunction reprty then 
+                    FunctionClosureValue reprty
+                    
+                // It must be exception, abstract, record or union.
+                // Either way we assume the only properties defined on
+                // the type are the actual fields of the type.  Again,
+                // we should be reading attributes here that indicate the
+                // true structure of the type, e.g. the order of the fields.   
+                elif FSharpType.IsUnion(reprty,bindingFlags) then 
+                    let tag,vals = FSharpValue.GetUnionFields (obj,reprty,bindingFlags) 
+                    let props = tag.GetFields()
+                    let pvals = (props,vals) ||> Array.map2 (fun prop v -> prop.Name,v)
+                    ConstructorValue(tag.Name, Array.toList pvals)
+
+                elif FSharpType.IsExceptionRepresentation(reprty,bindingFlags) then 
+                    let props = FSharpType.GetExceptionFields(reprty,bindingFlags) 
+                    let vals = FSharpValue.GetExceptionFields(obj,bindingFlags) 
+                    let pvals = (props,vals) ||> Array.map2 (fun prop v -> prop.Name,v)
+                    ExceptionValue(reprty, pvals |> Array.toList)
+
+                elif FSharpType.IsRecord(reprty,bindingFlags) then 
+                    let props = FSharpType.GetRecordFields(reprty,bindingFlags) 
+                    RecordValue(props |> Array.map (fun prop -> prop.Name, prop.GetValue(obj,null)) |> Array.toList)
+                else
+                    ObjectValue(obj)
+
+            // This one is like the above but can make use of additional
+            // statically-known type information to aid in the
+            // analysis of null values. 
+
+            let GetValueInfo bindingFlags (x : 'a)  (* x could be null *) = 
+                let obj = (box x)
+                match obj with 
+                | null -> 
+                   let typ = typeof<'a>
+                   if isOptionType typ then  ConstructorValue("None", [])
+                   elif isUnitType typ then  UnitValue
+                   else ObjectValue(obj)
+                | _ -> 
+                  GetValueInfoOfObject bindingFlags (obj) 
+
+
+            let GetInfo bindingFlags (v:'a) = GetValueInfo bindingFlags (v:'a)
+
+    [<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+    module Display = 
+
+        open ReflectUtils
+        open LayoutOps
+        let string_of_int (i:int) = i.ToString()
+
+        let typeUsesSystemObjectToString (typ:System.Type) =
+            try let methInfo = typ.GetMethod("ToString",BindingFlags.Public ||| BindingFlags.Instance,null,[| |],null)
+                methInfo.DeclaringType = typeof<System.Object>
+            with e -> false
+
+        /// If "str" ends with "ending" then remove it from "str", otherwise no change.
+        let trimEnding (ending:string) (str:string) =
+#if FX_NO_CULTURE_INFO_ARGS
+          if str.EndsWith(ending) then 
+#else
+          if str.EndsWith(ending,StringComparison.Ordinal) then 
+#endif
+              str.Substring(0,str.Length - ending.Length) 
+          else str
+
+        let catchExn f = try Choice1Of2 (f ()) with e -> Choice2Of2 e
+        
+        // An implementation of break stack.
+        // Uses mutable state, relying on linear threading of the state.
+
+        [<NoEquality; NoComparison>]
+        type Breaks = 
+            Breaks of
+                int *     // pos of next free slot 
+                int *     // pos of next possible "outer" break - OR - outer=next if none possible 
+                int array // stack of savings, -ve means it has been broken   
+
+        // next  is next slot to push into - aka size of current occupied stack.  
+        // outer counts up from 0, and is next slot to break if break forced.
+        // - if all breaks forced, then outer=next.
+        // - popping under these conditions needs to reduce outer and next.
+        
+
+        //let dumpBreaks prefix (Breaks(next,outer,stack)) = ()
+        //   printf "%s: next=%d outer=%d stack.Length=%d\n" prefix next outer stack.Length;
+        //   stdout.Flush() 
+             
+        let chunkN = 400      
+        let breaks0 () = Breaks(0,0,Array.create chunkN 0)
+
+        let pushBreak saving (Breaks(next,outer,stack)) =
+            //dumpBreaks "pushBreak" (next,outer,stack);
+            let stack = 
+                if next = stack.Length then
+                  Array.init (next + chunkN) (fun i -> if i < next then stack.[i] else 0) // expand if full 
+                else
+                  stack
+           
+            stack.[next] <- saving;
+            Breaks(next+1,outer,stack)
+
+        let popBreak (Breaks(next,outer,stack)) =
+            //dumpBreaks "popBreak" (next,outer,stack);
+            if next=0 then raise (Failure "popBreak: underflow");
+            let topBroke = stack.[next-1] < 0
+            let outer = if outer=next then outer-1 else outer  // if all broken, unwind 
+            let next  = next - 1
+            Breaks(next,outer,stack),topBroke
+
+        let forceBreak (Breaks(next,outer,stack)) =
+            //dumpBreaks "forceBreak" (next,outer,stack);
+            if outer=next then
+              // all broken 
+                None
+            else
+                let saving = stack.[outer]
+                stack.[outer] <- -stack.[outer];    
+                let outer = outer+1
+                Some (Breaks(next,outer,stack),saving)
+
+        // -------------------------------------------------------------------------
+        // fitting
+        // ------------------------------------------------------------------------
+          
+        let squashTo (maxWidth,leafFormatter) layout =
+            if maxWidth <= 0 then layout else 
+            let rec fit breaks (pos,layout) =
+                // breaks = break context, can force to get indentation savings.
+                // pos    = current position in line
+                // layout = to fit
+                //------
+                // returns:
+                // breaks
+                // layout - with breaks put in to fit it.
+                // pos    - current pos in line = rightmost position of last line of block.
+                // offset - width of last line of block
+                // NOTE: offset <= pos -- depending on tabbing of last block
+               
+                let breaks,layout,pos,offset =
+                    match layout with
+                    | Attr (tag,attrs,l) ->
+                        let breaks,layout,pos,offset = fit breaks (pos,l) 
+                        let layout = Attr (tag,attrs,layout) 
+                        breaks,layout,pos,offset
+                    | Leaf (jl,obj,jr) ->
+                        let text:string = leafFormatter obj 
+                        // save the formatted text from the squash
+                        let layout = Leaf(jl,(text :> obj),jr) 
+                        let textWidth = text.Length
+                        let rec fitLeaf breaks pos =
+                          if pos + textWidth <= maxWidth then
+                              breaks,layout,pos + textWidth,textWidth // great, it fits 
+                          else
+                              match forceBreak breaks with
+                              | None                 -> 
+                                  breaks,layout,pos + textWidth,textWidth // tough, no more breaks 
+                              | Some (breaks,saving) -> 
+                                  let pos = pos - saving 
+                                  fitLeaf breaks pos
+                       
+                        fitLeaf breaks pos
+                    | Node (jl,l,jm,r,jr,joint) ->
+                        let mid = if jm then 0 else 1
+                        match joint with
+                        | Unbreakable    ->
+                            let breaks,l,pos,offsetl = fit breaks (pos,l)    // fit left 
+                            let pos = pos + mid                              // fit space if juxt says so 
+                            let breaks,r,pos,offsetr = fit breaks (pos,r)    // fit right 
+                            breaks,Node (jl,l,jm,r,jr,Unbreakable),pos,offsetl + mid + offsetr
+                        | Broken indent ->
+                            let breaks,l,pos,offsetl = fit breaks (pos,l)    // fit left 
+                            let pos = pos - offsetl + indent                 // broken so - offset left + ident 
+                            let breaks,r,pos,offsetr = fit breaks (pos,r)    // fit right 
+                            breaks,Node (jl,l,jm,r,jr,Broken indent),pos,indent + offsetr
+                        | Breakable indent ->
+                            let breaks,l,pos,offsetl = fit breaks (pos,l)    // fit left 
+                            // have a break possibility, with saving 
+                            let saving = offsetl + mid - indent
+                            let pos = pos + mid
+                            if saving>0 then
+                                let breaks = pushBreak saving breaks
+                                let breaks,r,pos,offsetr = fit breaks (pos,r)
+                                let breaks,broken = popBreak breaks
+                                if broken then
+                                    breaks,Node (jl,l,jm,r,jr,Broken indent)   ,pos,indent + offsetr
+                                else
+                                    breaks,Node (jl,l,jm,r,jr,Breakable indent),pos,offsetl + mid + offsetr
+                            else
+                                // actually no saving so no break 
+                                let breaks,r,pos,offsetr = fit breaks (pos,r)
+                                breaks,Node (jl,l,jm,r,jr,Breakable indent)  ,pos,offsetl + mid + offsetr
+               
+               //Printf.printf "\nDone:     pos=%d offset=%d" pos offset;
+                breaks,layout,pos,offset
+           
+            let breaks = breaks0 ()
+            let pos = 0
+            let _,layout,_,_ = fit breaks (pos,layout)
+            layout
+
+        // -------------------------------------------------------------------------
+        // showL
+        // ------------------------------------------------------------------------
+
+        let combine strs = System.String.Concat(Array.ofList(strs) : string[])
+        let showL opts leafFormatter layout =
+            let push x rstrs = x::rstrs
+            let z0 = [],0
+            let addText (rstrs,i) (text:string) = push text rstrs,i + text.Length
+            let index   (_,i)               = i
+            let extract rstrs = combine(List.rev rstrs) 
+            let newLine (rstrs,_) n     = // \n then spaces... 
+                let indent = new System.String(' ', n)
+                let rstrs = push System.Environment.NewLine rstrs
+                let rstrs = push indent rstrs
+                rstrs,n
+
+            // addL: pos is tab level 
+            let rec addL z pos layout = 
+                match layout with 
+                | Leaf (_,obj,_)                 -> 
+                    let text = leafFormatter obj 
+                    addText z text
+                | Node (_,l,_,r,_,Broken indent) 
+                     // Print width = 0 implies 1D layout, no squash
+                     when not (opts.PrintWidth = 0)  -> 
+                    let z = addL z pos l
+                    let z = newLine z (pos+indent)
+                    let z = addL z (pos+indent) r
+                    z
+                | Node (_,l,jm,r,_,_)             -> 
+                    let z = addL z pos l
+                    let z = if jm then z else addText z " "
+                    let pos = index z
+                    let z = addL z pos r
+                    z
+                | Attr (_,_,l) ->
+                    addL z pos l
+           
+            let rstrs,_ = addL z0 0 layout
+            extract rstrs
+
+
+        // -------------------------------------------------------------------------
+        // outL
+        // ------------------------------------------------------------------------
+
+        let outL outAttribute leafFormatter (chan : TextWriter) layout =
+            // write layout to output chan directly 
+            let write (s:string) = chan.Write(s)
+            // z is just current indent 
+            let z0 = 0
+            let index i = i
+            let addText z text  = write text;  (z + text.Length)
+            let newLine _ n     = // \n then spaces... 
+                let indent = new System.String(' ',n)
+                chan.WriteLine();
+                write indent;
+                n
+                
+            // addL: pos is tab level 
+            let rec addL z pos layout = 
+                match layout with 
+                | Leaf (_,obj,_)                 -> 
+                    let text = leafFormatter obj 
+                    addText z text
+                | Node (_,l,_,r,_,Broken indent) -> 
+                    let z = addL z pos l
+                    let z = newLine z (pos+indent)
+                    let z = addL z (pos+indent) r
+                    z
+                | Node (_,l,jm,r,_,_)             -> 
+                    let z = addL z pos l
+                    let z = if jm then z else addText z " "
+                    let pos = index z
+                    let z = addL z pos r
+                    z 
+                | Attr (tag,attrs,l) ->
+                let _ = outAttribute tag attrs true
+                let z = addL z pos l
+                let _ = outAttribute tag attrs false
+                z
+           
+            let _ = addL z0 0 layout
+            ()
+
+        // --------------------------------------------------------------------
+        // pprinter: using general-purpose reflection...
+        // -------------------------------------------------------------------- 
+          
+        let getValueInfo bindingFlags (x:'a) = Value.GetInfo bindingFlags (x:'a)
+
+        let unpackCons recd =
+            match recd with 
+            | [(_,h);(_,t)] -> (h,t)
+            | _             -> failwith "unpackCons"
+
+        let getListValueInfo bindingFlags (x:obj) =
+            match x with 
+            | null -> None 
+            | _ -> 
+                match getValueInfo bindingFlags x with
+                | ConstructorValue ("Cons",recd) -> Some (unpackCons recd)
+                | ConstructorValue ("Empty",[]) -> None
+                | _ -> failwith "List value had unexpected ValueInfo"
+
+        let compactCommaListL xs = sepListL (sepL ",") xs // compact, no spaces around "," 
+        let nullL = wordL "null"
+        let measureL = wordL "()"
+          
+        // --------------------------------------------------------------------
+        // pprinter: attributes
+        // -------------------------------------------------------------------- 
+
+        let makeRecordVerticalL nameXs =
+            let itemL (name,xL) = let labelL = wordL name in ((labelL ^^ wordL "=")) -- (xL  ^^ (rightL ";"))
+            let braceL xs = (leftL "{") ^^ xs ^^ (rightL "}")
+            braceL (aboveListL (List.map itemL nameXs))
+
+        let makeRecordHorizontalL nameXs = (* This is a more compact rendering of records - and is more like tuples *)
+            let itemL (name,xL) = let labelL = wordL name in ((labelL ^^ wordL "=")) -- xL
+            let braceL xs = (leftL "{") ^^ xs ^^ (rightL "}")
+            braceL (sepListL (rightL ";")  (List.map itemL nameXs))
+
+        let makeRecordL nameXs = makeRecordVerticalL nameXs (* REVIEW: switch to makeRecordHorizontalL ? *)
+
+        let makePropertiesL nameXs =
+            let itemL (name,v) = 
+               let labelL = wordL name 
+               (labelL ^^ wordL "=")
+               ^^ (match v with 
+                   | None -> wordL "?" 
+                   | Some xL -> xL)
+               ^^ (rightL ";")
+            let braceL xs = (leftL "{") ^^ xs ^^ (rightL "}")
+            braceL (aboveListL (List.map itemL nameXs))
+
+        let makeListL itemLs =
+            (leftL "[") 
+            ^^ sepListL (rightL ";") itemLs 
+            ^^ (rightL "]")
+
+        let makeArrayL xs =
+            (leftL "[|") 
+            ^^ sepListL (rightL ";") xs 
+            ^^ (rightL "|]")
+
+        let makeArray2L xs = leftL "[" ^^ aboveListL xs ^^ rightL "]"  
+
+        // --------------------------------------------------------------------
+        // pprinter: anyL - support functions
+        // -------------------------------------------------------------------- 
+
+        let getProperty (obj: obj) name =
+            let ty = obj.GetType()
+#if FX_NO_CULTURE_INFO_ARGS
+            ty.InvokeMember(name, (BindingFlags.GetProperty ||| BindingFlags.Instance ||| BindingFlags.Public ||| BindingFlags.NonPublic), null, obj, [| |])
+#else
+            ty.InvokeMember(name, (BindingFlags.GetProperty ||| BindingFlags.Instance ||| BindingFlags.Public ||| BindingFlags.NonPublic), null, obj, [| |],CultureInfo.InvariantCulture)
+#endif
+
+        let formatChar isChar c = 
+            match c with 
+            | '\'' when isChar -> "\\\'"
+            | '\"' when not isChar -> "\\\""
+            //| '\n' -> "\\n"
+            //| '\r' -> "\\r"
+            //| '\t' -> "\\t"
+            | '\\' -> "\\\\"
+            | '\b' -> "\\b"
+            | _ when System.Char.IsControl(c) -> 
+                 let d1 = (int c / 100) % 10 
+                 let d2 = (int c / 10) % 10 
+                 let d3 = int c % 10 
+                 "\\" + d1.ToString() + d2.ToString() + d3.ToString()
+            | _ -> c.ToString()
+            
+        let formatString (s:string) =
+            let rec check i = i < s.Length && not (System.Char.IsControl(s,i)) && s.[i] <> '\"' && check (i+1) 
+            let rec conv i acc = if i = s.Length then combine (List.rev acc) else conv (i+1) (formatChar false s.[i] :: acc)  
+            "\"" + s + "\""
+            // REVIEW: should we check for the common case of no control characters? Reinstate the following?
+            //"\"" + (if check 0 then s else conv 0 []) + "\""
+
+        let formatStringInWidth (width:int) (str:string) =
+            // Return a truncated version of the string, e.g.
+            //   "This is the initial text, which has been truncat"+[12 chars]
+            //
+            // Note: The layout code forces breaks based on leaf size and possible break points.
+            //       It does not force leaf size based on width.
+            //       So long leaf-string width can not depend on their printing context...
+            //
+            // The suffix like "+[dd chars]" is 11 chars.
+            //                  12345678901
+            let suffixLength    = 11 // turning point suffix length
+            let prefixMinLength = 12 // arbitrary. If print width is reduced, want to print a minimum of information on strings...
+            let prefixLength = max (width - 2 (*quotes*) - suffixLength) prefixMinLength
+            "\"" + (str.Substring(0,prefixLength)) + "\"" + "+[" + (str.Length - prefixLength).ToString() + " chars]"
+
+        // --------------------------------------------------------------------
+        // pprinter: anyL
+        // -------------------------------------------------------------------- 
+                           
+        type Precedence = 
+            | BracketIfTupleOrNotAtomic = 2
+            | BracketIfTuple = 3
+            | NeverBracket = 4
+
+        // In fsi.exe, certain objects are not printed for top-level bindings.
+        [<StructuralEquality; NoComparison>]
+        type ShowMode = 
+            | ShowAll 
+            | ShowTopLevelBinding
+
+        // polymorphic and inner recursion limitations prevent us defining polyL in the recursive loop 
+        let polyL bindingFlags (objL: ShowMode -> int -> Precedence -> ValueInfo -> obj -> Layout) showMode i prec  (x:'a) (* x could be null *) =
+            objL showMode i prec (getValueInfo bindingFlags (x:'a))  (box x) 
+
+        let anyL showMode bindingFlags (opts:FormatOptions) (x:'a) =
+            // showMode = ShowTopLevelBinding on the outermost expression when called from fsi.exe,
+            // This allows certain outputs, e.g. objects that would print as <seq> to be suppressed, etc. See 4343.
+            // Calls to layout proper sub-objects should pass showMode = ShowAll.
+
+            // Precedences to ensure we add brackets in the right places
+            
+            // Keep a record of objects encountered along the way
+            let path = Dictionary<obj,int>(10,HashIdentity.Reference)
+
+            // Roughly count the "nodes" printed, e.g. leaf items and inner nodes, but not every bracket and comma.
+            let size = ref opts.PrintSize
+            let exceededPrintSize() = !size<=0
+            let countNodes n = if !size > 0 then size := !size - n else () (* no need to keep decrementing (and avoid wrap around) *)
+            let stopShort _ = exceededPrintSize() // for unfoldL
+
+            // Recursive descent
+            let rec objL depthLim prec (x:obj) = polyL bindingFlags objWithReprL ShowAll  depthLim prec x (* showMode for inner expr *)
+            and sameObjL depthLim prec (x:obj) = polyL bindingFlags objWithReprL showMode depthLim prec x (* showMode preserved *)
+
+            and objWithReprL showMode depthLim prec (info:ValueInfo) (x:obj) (* x could be null *) =
+                try
+                  if depthLim<=0 || exceededPrintSize() then wordL "..." else
+                  match x with 
+                  | null -> 
+                    reprL showMode (depthLim-1) prec info x
+                  | _    ->
+                    if (path.ContainsKey(x)) then 
+                       wordL "..."
+                    else 
+                        path.Add(x,0);
+                        let res = 
+                          // Lazy<T> values. VS2008 used StructuredFormatDisplayAttribute to show via ToString. Dev10 (no attr) needs a special case.
+                          let ty = x.GetType()
+                          if ty.IsGenericType && ty.GetGenericTypeDefinition() = typedefof<Lazy<_>> then
+                            Some (wordL (x.ToString()))
+                          else
+                            // Try the StructuredFormatDisplayAttribute extensibility attribute
+                            match x.GetType().GetCustomAttributes (typeof<StructuredFormatDisplayAttribute>, true) with
+                            | null | [| |] -> None
+                            | res -> 
+                               let attr = (res.[0] :?> StructuredFormatDisplayAttribute) 
+                               let txt = attr.Value
+                               if txt = null || txt.Length <= 1 then  
+                                   None
+                               else
+                                  let p1 = txt.IndexOf ("{", StringComparison.Ordinal)
+                                  let p2 = txt.LastIndexOf ("}", StringComparison.Ordinal)
+                                  if p1 < 0 || p2 < 0 || p1+1 >= p2 then 
+                                      None 
+                                  else
+                                      let preText = if p1 <= 0 then "" else txt.[0..p1-1]
+                                      let postText = if p2+1 >= txt.Length then "" else txt.[p2+1..]
+                                      let prop = txt.[p1+1..p2-1]
+                                      match catchExn (fun () -> getProperty x prop) with
+                                        | Choice2Of2 e -> Some (wordL ("<StructuredFormatDisplay exception: " + e.Message + ">"))
+                                        | Choice1Of2 alternativeObj ->
+                                            try 
+                                                let alternativeObjL = 
+                                                  match alternativeObj with 
+                                                      // A particular rule is that if the alternative property
+                                                      // returns a string, we turn off auto-quoting and esaping of
+                                                      // the string, i.e. just treat the string as display text.
+                                                      // This allows simple implementations of 
+                                                      // such as
+                                                      //
+                                                      //    [<StructuredFormatDisplay("{StructuredDisplayString}I")>]
+                                                      //    type BigInt(signInt:int, v : BigNat) =
+                                                      //        member x.StructuredDisplayString = x.ToString()
+                                                      //
+                                                      | :? string as s -> sepL s
+                                                      | _ -> sameObjL (depthLim-1) Precedence.BracketIfTuple alternativeObj
+                                                countNodes 0 (* 0 means we do not count the preText and postText *)
+                                                Some (leftL preText ^^ alternativeObjL ^^ rightL postText)
+                                            with _ -> 
+                                              None
+
+                        let res = 
+                            match res with 
+                            | Some res -> res
+                            | None     -> reprL showMode (depthLim-1) prec info x
+                        path .Remove(x) |> ignore;
+                        res
+                with
+                  e ->
+                    countNodes 1
+                    wordL ("Error: " + e.Message)
+
+            and recdAtomicTupleL depthLim recd =
+                // tuples up args to UnionConstruction or ExceptionConstructor. no node count.
+                match recd with 
+                | [(_,x)] -> objL depthLim Precedence.BracketIfTupleOrNotAtomic x 
+                | txs     -> leftL "(" ^^ compactCommaListL (List.map (snd >> objL depthLim Precedence.BracketIfTuple) txs) ^^ rightL ")" 
+
+            and bracketIfL b basicL =
+                if b then (leftL "(") ^^ basicL ^^ (rightL ")") else basicL
+
+            and reprL showMode depthLim prec repr x (* x could be null *) =
+                let showModeFilter lay = match showMode with ShowAll -> lay | ShowTopLevelBinding -> emptyL                                                             
+                match repr with 
+                | TupleValue vals -> 
+                    let basicL = sepListL (rightL ",") (List.map (objL depthLim Precedence.BracketIfTuple ) vals)
+                    bracketIfL (prec <= Precedence.BracketIfTuple) basicL 
+
+                | RecordValue items -> 
+                    let itemL (name,x) =
+                      countNodes 1 // record labels are counted as nodes. [REVIEW: discussion under 4090].
+                      (name,objL depthLim Precedence.BracketIfTuple x)
+                    makeRecordL (List.map itemL items)
+
+                | ConstructorValue (constr,recd) when (* x is List<T>. Note: "null" is never a valid list value. *)
+                                                      x<>null && Type.IsListType (x.GetType()) ->
+                    match constr with 
+                    | "Cons" -> 
+                        let (x,xs) = unpackCons recd
+                        let project xs = getListValueInfo bindingFlags xs
+                        let itemLs = objL depthLim Precedence.BracketIfTuple x :: boundedUnfoldL (objL depthLim Precedence.BracketIfTuple) project stopShort xs (opts.PrintLength - 1)
+                        makeListL itemLs
+                    | _ ->
+                        countNodes 1
+                        wordL "[]" 
+
+                | ConstructorValue(nm,[])   ->
+                    countNodes 1
+                    (wordL nm)
+
+                | ConstructorValue(nm,recd) ->
+                    countNodes 1 (* e.g. Some (Some (Some (Some 2))) should count for 5 *)
+                    (wordL nm --- recdAtomicTupleL depthLim recd) |> bracketIfL (prec <= Precedence.BracketIfTupleOrNotAtomic)
+
+                | ExceptionValue(ty,recd) ->
+                    countNodes 1
+                    let name = ty.Name 
+                    match recd with
+                      | []   -> (wordL name)
+                      | recd -> (wordL name --- recdAtomicTupleL depthLim recd) |> bracketIfL (prec <= Precedence.BracketIfTupleOrNotAtomic)
+
+                | FunctionClosureValue ty ->
+                    // Q: should function printing include the ty.Name? It does not convey much useful info to most users, e.g. "clo@0_123".    
+                    countNodes 1
+                    wordL ("<fun:"+ty.Name+">") |> showModeFilter
+
+                | ObjectValue(obj)  ->
+                    match obj with 
+                    | null -> (countNodes 1; nullL)
+                    | _ -> 
+                    let ty = obj.GetType()
+                    match obj with 
+                    | :? string as s ->
+                        countNodes 1
+                        wordL (formatString s)  
+                    | :? System.Array as arr -> 
+                        match arr.Rank with
+                        | 1 -> 
+                             let n = arr.Length
+                             let b1 = arr.GetLowerBound(0) 
+                             let project depthLim = if depthLim=(b1+n) then None else Some (box (arr.GetValue(depthLim)),depthLim+1)
+                             let itemLs = boundedUnfoldL (objL depthLim Precedence.BracketIfTuple) project stopShort b1 opts.PrintLength
+                             makeArrayL (if b1 = 0 then itemLs else wordL("bound1="+string_of_int b1)::itemLs)
+                        | 2 -> 
+                             let n1 = arr.GetLength(0)
+                             let n2 = arr.GetLength(1)
+                             let b1 = arr.GetLowerBound(0) 
+                             let b2 = arr.GetLowerBound(1) 
+                             let project2 x y =
+                               if x>=(b1+n1) || y>=(b2+n2) then None
+                               else Some (box (arr.GetValue(x,y)),y+1)
+                             let rowL x = boundedUnfoldL (objL depthLim Precedence.BracketIfTuple) (project2 x) stopShort b2 opts.PrintLength |> makeListL
+                             let project1 x = if x>=(b1+n1) then None else Some (x,x+1)
+                             let rowsL  = boundedUnfoldL rowL project1 stopShort b1 opts.PrintLength
+                             makeArray2L (if b1=0 && b2 = 0 then rowsL else wordL("bound1=" + string_of_int b1)::wordL("bound2=" + string_of_int b2)::rowsL)
+                          | n -> 
+                             makeArrayL [wordL("rank=" + string_of_int n)]
+                        
+                    // Format 'set' and 'map' nicely
+                    | _ when  
+                          (let ty = obj.GetType()
+                           ty.IsGenericType && (ty.GetGenericTypeDefinition() = typedefof<Map<int,int>> 
+                                                || ty.GetGenericTypeDefinition() = typedefof<Set<int>>) ) ->
+                         let ty = obj.GetType()
+                         let word = if ty.GetGenericTypeDefinition() = typedefof<Map<int,int>> then "map" else "set"
+                         let possibleKeyValueL v = 
+                             if word = "map" &&
+                                (match v with null -> false | _ -> true) && 
+                                v.GetType().IsGenericType && 
+                                v.GetType().GetGenericTypeDefinition() = typedefof<KeyValuePair<int,int>> then
+                                  objL depthLim Precedence.BracketIfTuple (v.GetType().GetProperty("Key").GetValue(v, [| |]), 
+                                                                           v.GetType().GetProperty("Value").GetValue(v, [| |]))
+                             else
+                                  objL depthLim Precedence.BracketIfTuple v
+                         let it = (obj :?>  System.Collections.IEnumerable).GetEnumerator() 
+                         try 
+                           let itemLs = boundedUnfoldL possibleKeyValueL (fun () -> if it.MoveNext() then Some(it.Current,()) else None) stopShort () (1+opts.PrintLength/12)
+                           (wordL word --- makeListL itemLs) |> bracketIfL (prec <= Precedence.BracketIfTupleOrNotAtomic)
+                         finally 
+                            match it with 
+                            | :? System.IDisposable as e -> e.Dispose()
+                            | _ -> ()
+
+                    | :? System.Collections.IEnumerable as ie ->
+                         if opts.ShowIEnumerable then
+                           let word = "seq"
+                           let it = ie.GetEnumerator() 
+                           try 
+                             let itemLs = boundedUnfoldL (objL depthLim Precedence.BracketIfTuple) (fun () -> if it.MoveNext() then Some(it.Current,()) else None) stopShort () (1+opts.PrintLength/30)
+                             (wordL word --- makeListL itemLs) |> bracketIfL (prec <= Precedence.BracketIfTupleOrNotAtomic)
+                           finally 
+                              match it with 
+                              | :? System.IDisposable as e -> e.Dispose()
+                              | _ -> ()
+                             
+                         else
+                           // Sequence printing is turned off for declared-values, and maybe be disabled to users.
+                           // There is choice here, what to print? <seq> or ... or ?
+                           // Also, in the declared values case, if the sequence is actually a known non-lazy type (list, array etc etc) we could print it.  
+                           wordL "<seq>" |> showModeFilter
+                    | _ ->
+                         if showMode = ShowTopLevelBinding && typeUsesSystemObjectToString (obj.GetType()) then
+                           emptyL
+                         else
+                           countNodes 1
+                           let basicL = LayoutOps.objL obj  // This buries an obj in the layout, rendered at squash time via a leafFormatter.
+                                                            // If the leafFormatter was directly here, then layout leaves could store strings.
+                           match obj with 
+                           | _ when opts.ShowProperties ->
+                              let props = ty.GetProperties(BindingFlags.GetField ||| BindingFlags.Instance ||| BindingFlags.Public)
+                              // massively reign in deep printing of properties 
+                              let nDepth = depthLim/10
+                              System.Array.Sort((props:>System.Array),{ new System.Collections.IComparer with member this.Compare(p1,p2) = compare ((p1 :?> PropertyInfo).Name) ((p2 :?> PropertyInfo).Name) } );
+                              if props.Length = 0 || (nDepth <= 0) then basicL 
+                              else basicL --- 
+                                     (props 
+                                      |> Array.toList 
+                                      |> List.map (fun p -> (p.Name,(try Some (objL nDepth Precedence.BracketIfTuple (getProperty obj p.Name)) 
+                                                                     with _ -> None)))
+                                      |> makePropertiesL)
+                           | _ -> basicL 
+                | UnitValue -> countNodes 1; measureL
+
+            polyL bindingFlags objWithReprL showMode opts.PrintDepth Precedence.BracketIfTuple x
+
+        // --------------------------------------------------------------------
+        // pprinter: leafFormatter
+        // --------------------------------------------------------------------
+
+#if Suggestion4299
+        // See bug 4299. Suppress FSI_dddd+<etc> from fsi printer.
+        let fixupForInteractiveFSharpClassesWithNoToString obj (text:string) =
+              // Given obj:T.
+              // If T is a nested type inside a parent type called FSI_dddd, then it looks like an F# Interactive type.
+              // Further, if the .ToString() text starts with "FSI_dddd+T" then it looks like it's the default ToString.
+              // A better test: it is default ToString if the MethodInfo.DeclaringType is System.Object.
+              // In this case, replace "FSI_dddd+T" by "T".
+              // assert(obj <> null)
+              let fullName = obj.GetType().FullName // e.g. "FSI_0123+Name"
+              let name     = obj.GetType().Name     // e.g. "Name"
+              let T = obj.GetType()      
+              if text.StartsWith(fullName) then
+                  // text could be a default .ToString() since it starts with the FullName of the type. More checks...
+                  if T.IsNested &&
+                     T.DeclaringType.Name.StartsWith("FSI_") &&                             // Name has "FSI_" which is 
+                     T.DeclaringType.Name.Substring(4) |> Seq.forall System.Char.IsDigit    // followed by digits?
+                  then
+                      name ^ text.Substring(fullName.Length)    // replace fullName by name at start of text
+                  else
+                      text
+              else
+                text
+#endif
+
+        let leafFormatter (opts:FormatOptions) (obj :obj) =
+            match obj with 
+            | null -> "null"
+            | :? double as d -> 
+                let s = d.ToString(opts.FloatingPointFormat,opts.FormatProvider)
+                if System.Double.IsNaN(d) then "nan"
+                elif System.Double.IsNegativeInfinity(d) then "-infinity"
+                elif System.Double.IsPositiveInfinity(d) then "infinity"
+                elif opts.FloatingPointFormat.[0] = 'g'  && String.forall(fun c -> System.Char.IsDigit(c) || c = '-')  s
+                then s + ".0" 
+                else s
+            | :? single as d -> 
+                (if System.Single.IsNaN(d) then "nan"
+                 elif System.Single.IsNegativeInfinity(d) then "-infinity"
+                 elif System.Single.IsPositiveInfinity(d) then "infinity"
+                 elif opts.FloatingPointFormat.Length >= 1 && opts.FloatingPointFormat.[0] = 'g' 
+                  && float32(System.Int32.MinValue) < d && d < float32(System.Int32.MaxValue) 
+                  && float32(int32(d)) = d 
+                 then (System.Convert.ToInt32 d).ToString(opts.FormatProvider) + ".0"
+                 else d.ToString(opts.FloatingPointFormat,opts.FormatProvider)) 
+                + "f"
+            | :? System.Decimal as d -> d.ToString("g",opts.FormatProvider) + "M"
+            | :? uint64 as d -> d.ToString(opts.FormatProvider) + "UL"
+            | :? int64  as d -> d.ToString(opts.FormatProvider) + "L"
+            | :? int32  as d -> d.ToString(opts.FormatProvider)
+            | :? uint32 as d -> d.ToString(opts.FormatProvider) + "u"
+            | :? int16  as d -> d.ToString(opts.FormatProvider) + "s"
+            | :? uint16 as d -> d.ToString(opts.FormatProvider) + "us"
+            | :? sbyte  as d -> d.ToString(opts.FormatProvider) + "y"
+            | :? byte   as d -> d.ToString(opts.FormatProvider) + "uy"
+            | :? nativeint as d -> d.ToString() + "n"
+            | :? unativeint  as d -> d.ToString() + "un"
+            | :? bool   as b -> (if b then "true" else "false")
+            | :? char   as c -> "\'" + formatChar true c + "\'"
+            | _ -> try  let text = obj.ToString()
+                        text
+                   with e ->
+                     // If a .ToString() call throws an exception, catch it and use the message as the result.
+                     // This may be informative, e.g. division by zero etc...
+                     "<ToString exception: " + e.Message + ">" 
+
+        let any_to_layout opts x = anyL ShowAll BindingFlags.Public opts x
+
+        let squash_layout opts l = 
+            // Print width = 0 implies 1D layout, no squash
+            if opts.PrintWidth = 0 then 
+                l 
+            else 
+                l |> squashTo (opts.PrintWidth,leafFormatter opts)
+
+        let output_layout opts oc l = 
+            l |> squash_layout opts 
+              |> outL opts.AttributeProcessor (leafFormatter opts) oc
+
+        let layout_to_string opts l = 
+            l |> squash_layout opts 
+              |> showL opts (leafFormatter opts) 
+
+        let output_any_ex opts oc x = x |> any_to_layout opts |> output_layout opts oc
+
+        let output_any oc x = output_any_ex FormatOptions.Default oc x
+
+        let layout_as_string opts x = x |> any_to_layout opts |> layout_to_string opts
+
+        let any_to_string x = layout_as_string FormatOptions.Default x
+
+
--- fsharp-3.1.1.26+dfsg2.orig/FSharp.PowerPack/StructuredFormat.fsi
+++ fsharp-3.1.1.26+dfsg2/FSharp.PowerPack/StructuredFormat.fsi
@@ -1,188 +1,188 @@
-//=========================================================================
-// (c) Microsoft Corporation 2005-2009. 
-//=========================================================================
-
-namespace Microsoft.FSharp.Text.StructuredFormat
-
-    open System
-    open System.IO
-
-    /// Data representing joints in structured layouts of terms.  The representation
-    /// of this data type is only for the consumption of formatting engines.
-    [<StructuralEquality; NoComparison>]
-    type Joint =
-        | Unbreakable
-        | Breakable of int
-        | Broken of int
-
-    /// Data representing structured layouts of terms.  The representation
-    /// of this data type is only for the consumption of formatting engines.
-    [<NoEquality; NoComparison>]
-    type Layout =
-     | Leaf of bool * obj * bool
-     | Node of bool * Layout * bool * Layout * bool * Joint
-     | Attr of string * (string * string) list * Layout
-
-
-    type IEnvironment = 
-        /// Return to the layout-generation 
-        /// environment to layout any otherwise uninterpreted object
-        abstract GetLayout : obj -> Layout
-        /// The maximum number of elements for which to generate layout for 
-        /// list-like structures, or columns in table-like 
-        /// structures.  -1 if no maximum.
-        abstract MaxColumns : int
-        /// The maximum number of rows for which to generate layout for table-like 
-        /// structures.  -1 if no maximum.
-        abstract MaxRows : int
-      
-    /// A layout is a sequence of strings which have been joined together.
-    /// The strings are classified as words, separators and left and right parenthesis.
-    /// This classification determines where spaces are inserted.
-    /// A joint is either unbreakable, breakable or broken.
-    /// If a joint is broken the RHS layout occurs on the next line with optional indentation.
-    /// A layout can be squashed to for given width which forces breaks as required.
-    [<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
-    module LayoutOps =
-
-        /// The empty layout
-        val emptyL     : Layout
-        /// Is it the empty layout?
-        val isEmptyL   : layout:Layout -> bool
-        
-        /// An uninterpreted leaf, to be interpreted into a string
-        /// by the layout engine. This allows leaf layouts for numbers, strings and
-        /// other atoms to be customized according to culture.
-        val objL       : value:obj -> Layout
-
-        /// An string leaf 
-        val wordL      : text:string -> Layout
-        /// An string which requires no spaces either side.
-        val sepL       : text:string -> Layout
-        /// An string which is right parenthesis (no space on the left).
-        val rightL     : text:string -> Layout
-        /// An string which is left  parenthesis (no space on the right).
-        val leftL      : text:string -> Layout
-
-        /// Join, unbreakable. 
-        val ( ^^ )     : layout1:Layout -> layout2:Layout -> Layout   
-        /// Join, possible break with indent=0
-        val ( ++ )     : layout1:Layout -> layout2:Layout -> Layout   
-        /// Join, possible break with indent=1
-        val ( -- )     : layout1:Layout -> layout2:Layout -> Layout   
-        /// Join, possible break with indent=2 
-        val ( --- )    : layout1:Layout -> layout2:Layout -> Layout   
-        /// Join broken with ident=0
-        val ( @@ )     : layout1:Layout -> layout2:Layout -> Layout   
-        /// Join broken with ident=1 
-        val ( @@- )    : layout1:Layout -> layout2:Layout -> Layout   
-        /// Join broken with ident=2 
-        val ( @@-- )   : layout1:Layout -> layout2:Layout -> Layout   
-
-        /// Join layouts into a comma separated list.
-        val commaListL : layouts:Layout list -> Layout
-          
-        /// Join layouts into a space separated list.    
-        val spaceListL : layouts:Layout list -> Layout
-          
-        /// Join layouts into a semi-colon separated list.
-        val semiListL  : layouts:Layout list -> Layout
-
-        /// Join layouts into a list separated using the given Layout.
-        val sepListL   : layout1:Layout -> layouts:Layout list -> Layout
-
-        /// Wrap round brackets around Layout.
-        val bracketL   : Layout:Layout -> Layout
-        /// Wrap square brackets around layout.    
-        val squareBracketL   : layout:Layout -> Layout
-        /// Wrap braces around layout.        
-        val braceL     : layout:Layout -> Layout
-        /// Form tuple of layouts.            
-        val tupleL     : layouts:Layout list -> Layout
-        /// Layout two vertically.
-        val aboveL     : layout1:Layout -> layout2:Layout -> Layout
-        /// Layout list vertically.    
-        val aboveListL : layouts:Layout list -> Layout
-
-        /// Layout like an F# option.
-        val optionL    : selector:('T -> Layout) -> value:'T option -> Layout
-        /// Layout like an F# list.    
-        val listL      : selector:('T -> Layout) -> value:'T list   -> Layout
-
-        /// See tagL
-        val tagAttrL : text:string -> maps:(string * string) list -> layout:Layout -> Layout
-
-        /// For limitting layout of list-like sequences (lists,arrays,etc).
-        /// unfold a list of items using (project and z) making layout list via itemL.
-        /// If reach maxLength (before exhausting) then truncate.
-        val unfoldL : selector:('T -> Layout) -> folder:('State -> ('T * 'State) option) -> state:'State -> count:int -> Layout list
-
-    /// A record of options to control structural formatting.
-    /// For F# Interactive properties matching those of this value can be accessed via the 'fsi'
-    /// value.
-    /// 
-    /// Floating Point format given in the same format accepted by System.Double.ToString,
-    /// e.g. f6 or g15.
-    ///
-    /// If ShowProperties is set the printing process will evaluate properties of the values being
-    /// displayed.  This may cause additional computation.  
-    ///
-    /// The ShowIEnumerable is set the printing process will force the evalution of IEnumerable objects
-    /// to a small, finite depth, as determined by the printing parameters.
-    /// This may lead to additional computation being performed during printing.
-    ///
-    /// <example>
-    /// From F# Interactive the default settings can be adjusted using, for example, 
-    /// <pre>
-    ///   open Microsoft.FSharp.Compiler.Interactive.Settings;;
-    ///   setPrintWidth 120;;
-    /// </pre>
-    /// </example>
-    [<NoEquality; NoComparison>]
-    type FormatOptions = 
-        { FloatingPointFormat: string
-          AttributeProcessor: (string -> (string * string) list -> bool -> unit);
-          FormatProvider: System.IFormatProvider
-          BindingFlags: System.Reflection.BindingFlags
-          PrintWidth : int 
-          PrintDepth : int 
-          PrintLength : int
-          PrintSize : int  
-          ShowProperties : bool
-          ShowIEnumerable: bool  }
-        static member Default : FormatOptions
-
-    [<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
-    module Display = 
-
-
-        /// Convert any value to a string using a standard formatter
-        /// Data is typically formatted in a structured format, e.g.
-        /// lists are formatted using the "[1;2]" notation.
-        /// The details of the format are not specified and may change
-        /// from version to version and according to the flags given
-        /// to the F# compiler.  The format is intended to be human-readable,
-        /// not machine readable.  If alternative generic formats are required
-        /// you should develop your own formatter, using the code in the
-        /// implementation of this file as a starting point.
-        ///
-        /// Data from other .NET languages is formatted using a virtual
-        /// call to Object.ToString() on the boxed version of the input.
-        val any_to_string: value:'T -> string
-
-        /// Ouput any value to a channel using the same set of formatting rules
-        /// as any_to_string
-        val output_any: writer:TextWriter -> value:'T -> unit
-
-        val any_to_layout   : options:FormatOptions -> value:'T -> Layout
-        val squash_layout   : options:FormatOptions -> layout:Layout -> Layout
-        val output_layout   : options:FormatOptions -> writer:TextWriter -> layout:Layout -> unit
-        val layout_as_string: options:FormatOptions -> value:'T -> string
-
-        /// Convert any value to a layout using the given formatting options.  The
-        /// layout can then be processed using formatting display engines such as
-        /// those in the LayoutOps module.  any_to_string and output_any are
-        /// built using any_to_layout with default format options.
-        val layout_to_string: options:FormatOptions -> layout:Layout -> string
-
-
+//=========================================================================
+// (c) Microsoft Corporation 2005-2009. 
+//=========================================================================
+
+namespace Microsoft.FSharp.Text.StructuredFormat
+
+    open System
+    open System.IO
+
+    /// Data representing joints in structured layouts of terms.  The representation
+    /// of this data type is only for the consumption of formatting engines.
+    [<StructuralEquality; NoComparison>]
+    type Joint =
+        | Unbreakable
+        | Breakable of int
+        | Broken of int
+
+    /// Data representing structured layouts of terms.  The representation
+    /// of this data type is only for the consumption of formatting engines.
+    [<NoEquality; NoComparison>]
+    type Layout =
+     | Leaf of bool * obj * bool
+     | Node of bool * Layout * bool * Layout * bool * Joint
+     | Attr of string * (string * string) list * Layout
+
+
+    type IEnvironment = 
+        /// Return to the layout-generation 
+        /// environment to layout any otherwise uninterpreted object
+        abstract GetLayout : obj -> Layout
+        /// The maximum number of elements for which to generate layout for 
+        /// list-like structures, or columns in table-like 
+        /// structures.  -1 if no maximum.
+        abstract MaxColumns : int
+        /// The maximum number of rows for which to generate layout for table-like 
+        /// structures.  -1 if no maximum.
+        abstract MaxRows : int
+      
+    /// A layout is a sequence of strings which have been joined together.
+    /// The strings are classified as words, separators and left and right parenthesis.
+    /// This classification determines where spaces are inserted.
+    /// A joint is either unbreakable, breakable or broken.
+    /// If a joint is broken the RHS layout occurs on the next line with optional indentation.
+    /// A layout can be squashed to for given width which forces breaks as required.
+    [<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+    module LayoutOps =
+
+        /// The empty layout
+        val emptyL     : Layout
+        /// Is it the empty layout?
+        val isEmptyL   : layout:Layout -> bool
+        
+        /// An uninterpreted leaf, to be interpreted into a string
+        /// by the layout engine. This allows leaf layouts for numbers, strings and
+        /// other atoms to be customized according to culture.
+        val objL       : value:obj -> Layout
+
+        /// An string leaf 
+        val wordL      : text:string -> Layout
+        /// An string which requires no spaces either side.
+        val sepL       : text:string -> Layout
+        /// An string which is right parenthesis (no space on the left).
+        val rightL     : text:string -> Layout
+        /// An string which is left  parenthesis (no space on the right).
+        val leftL      : text:string -> Layout
+
+        /// Join, unbreakable. 
+        val ( ^^ )     : layout1:Layout -> layout2:Layout -> Layout   
+        /// Join, possible break with indent=0
+        val ( ++ )     : layout1:Layout -> layout2:Layout -> Layout   
+        /// Join, possible break with indent=1
+        val ( -- )     : layout1:Layout -> layout2:Layout -> Layout   
+        /// Join, possible break with indent=2 
+        val ( --- )    : layout1:Layout -> layout2:Layout -> Layout   
+        /// Join broken with ident=0
+        val ( @@ )     : layout1:Layout -> layout2:Layout -> Layout   
+        /// Join broken with ident=1 
+        val ( @@- )    : layout1:Layout -> layout2:Layout -> Layout   
+        /// Join broken with ident=2 
+        val ( @@-- )   : layout1:Layout -> layout2:Layout -> Layout   
+
+        /// Join layouts into a comma separated list.
+        val commaListL : layouts:Layout list -> Layout
+          
+        /// Join layouts into a space separated list.    
+        val spaceListL : layouts:Layout list -> Layout
+          
+        /// Join layouts into a semi-colon separated list.
+        val semiListL  : layouts:Layout list -> Layout
+
+        /// Join layouts into a list separated using the given Layout.
+        val sepListL   : layout1:Layout -> layouts:Layout list -> Layout
+
+        /// Wrap round brackets around Layout.
+        val bracketL   : Layout:Layout -> Layout
+        /// Wrap square brackets around layout.    
+        val squareBracketL   : layout:Layout -> Layout
+        /// Wrap braces around layout.        
+        val braceL     : layout:Layout -> Layout
+        /// Form tuple of layouts.            
+        val tupleL     : layouts:Layout list -> Layout
+        /// Layout two vertically.
+        val aboveL     : layout1:Layout -> layout2:Layout -> Layout
+        /// Layout list vertically.    
+        val aboveListL : layouts:Layout list -> Layout
+
+        /// Layout like an F# option.
+        val optionL    : selector:('T -> Layout) -> value:'T option -> Layout
+        /// Layout like an F# list.    
+        val listL      : selector:('T -> Layout) -> value:'T list   -> Layout
+
+        /// See tagL
+        val tagAttrL : text:string -> maps:(string * string) list -> layout:Layout -> Layout
+
+        /// For limitting layout of list-like sequences (lists,arrays,etc).
+        /// unfold a list of items using (project and z) making layout list via itemL.
+        /// If reach maxLength (before exhausting) then truncate.
+        val unfoldL : selector:('T -> Layout) -> folder:('State -> ('T * 'State) option) -> state:'State -> count:int -> Layout list
+
+    /// A record of options to control structural formatting.
+    /// For F# Interactive properties matching those of this value can be accessed via the 'fsi'
+    /// value.
+    /// 
+    /// Floating Point format given in the same format accepted by System.Double.ToString,
+    /// e.g. f6 or g15.
+    ///
+    /// If ShowProperties is set the printing process will evaluate properties of the values being
+    /// displayed.  This may cause additional computation.  
+    ///
+    /// The ShowIEnumerable is set the printing process will force the evalution of IEnumerable objects
+    /// to a small, finite depth, as determined by the printing parameters.
+    /// This may lead to additional computation being performed during printing.
+    ///
+    /// <example>
+    /// From F# Interactive the default settings can be adjusted using, for example, 
+    /// <pre>
+    ///   open Microsoft.FSharp.Compiler.Interactive.Settings;;
+    ///   setPrintWidth 120;;
+    /// </pre>
+    /// </example>
+    [<NoEquality; NoComparison>]
+    type FormatOptions = 
+        { FloatingPointFormat: string
+          AttributeProcessor: (string -> (string * string) list -> bool -> unit);
+          FormatProvider: System.IFormatProvider
+          BindingFlags: System.Reflection.BindingFlags
+          PrintWidth : int 
+          PrintDepth : int 
+          PrintLength : int
+          PrintSize : int  
+          ShowProperties : bool
+          ShowIEnumerable: bool  }
+        static member Default : FormatOptions
+
+    [<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+    module Display = 
+
+
+        /// Convert any value to a string using a standard formatter
+        /// Data is typically formatted in a structured format, e.g.
+        /// lists are formatted using the "[1;2]" notation.
+        /// The details of the format are not specified and may change
+        /// from version to version and according to the flags given
+        /// to the F# compiler.  The format is intended to be human-readable,
+        /// not machine readable.  If alternative generic formats are required
+        /// you should develop your own formatter, using the code in the
+        /// implementation of this file as a starting point.
+        ///
+        /// Data from other .NET languages is formatted using a virtual
+        /// call to Object.ToString() on the boxed version of the input.
+        val any_to_string: value:'T -> string
+
+        /// Ouput any value to a channel using the same set of formatting rules
+        /// as any_to_string
+        val output_any: writer:TextWriter -> value:'T -> unit
+
+        val any_to_layout   : options:FormatOptions -> value:'T -> Layout
+        val squash_layout   : options:FormatOptions -> layout:Layout -> Layout
+        val output_layout   : options:FormatOptions -> writer:TextWriter -> layout:Layout -> unit
+        val layout_as_string: options:FormatOptions -> value:'T -> string
+
+        /// Convert any value to a layout using the given formatting options.  The
+        /// layout can then be processed using formatting display engines such as
+        /// those in the LayoutOps module.  any_to_string and output_any are
+        /// built using any_to_layout with default format options.
+        val layout_to_string: options:FormatOptions -> layout:Layout -> string
+
+
--- fsharp-3.1.1.26+dfsg2.orig/FSharp.PowerPack/TaggedCollections.fs
+++ fsharp-3.1.1.26+dfsg2/FSharp.PowerPack/TaggedCollections.fs
@@ -1,1179 +1,1179 @@
-// (c) Microsoft Corporation 2005-2009. 
-
-
-namespace Microsoft.FSharp.Collections.Tagged
-
-    #nowarn "51"
-    #nowarn "69" // interface implementations in augmentations
-    #nowarn "60" // override implementations in augmentations
-
-    open System
-    open System.Collections.Generic
-    open Microsoft.FSharp.Collections
-
-    [<CompilationRepresentation(CompilationRepresentationFlags.UseNullAsTrueValue)>]
-    [<NoEquality; NoComparison>]
-    type SetTree<'T> = 
-        | SetEmpty                                          // height = 0   
-        | SetNode of 'T * SetTree<'T> *  SetTree<'T> * int    // height = int 
-#if ONE
-        | SetOne  of 'T                                     // height = 1   
-#endif
-        // OPTIMIZATION: store SetNode(k,SetEmpty,SetEmpty,1) --->  SetOne(k) 
-
-
-    // CONSIDER: SetTree<'T> = SetEmpty | SetNode of 'T  * SetTree<'T> *  SetTree<'T> * int
-    //  with SetOne = SetNode of (x,null,null,1)
-
-    [<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
-    module SetTree = 
-        let empty = SetEmpty
-
-        let height t = 
-            match t with 
-            | SetEmpty -> 0
-#if ONE
-            | SetOne _ -> 1
-#endif
-            | SetNode (_,_,_,h) -> h
-
-#if CHECKED
-        let rec checkInvariant t =
-            // A good sanity check, loss of balance can hit perf 
-            match t with 
-            | SetEmpty -> true
-            | SetOne _ -> true
-            | SetNode (k,t1,t2,h) ->
-                let h1 = height t1 in
-                let h2 = height t2 in
-                (-2 <= (h1 - h2) && (h1 - h2) <= 2) && checkInvariant t1 && checkInvariant t2
-#else
-        let inline SetOne(x) = SetNode(x,SetEmpty,SetEmpty,1)
-#endif
-
-        let tolerance = 2
-
-        let mk l hl k r hr = 
-#if ONE
-            if hl = 0 && hr = 0 then SetOne (k)
-            else
-#endif
-              let m = if hl < hr then hr else hl 
-              SetNode(k,l,r,m+1)
-
-        let rebalance t1 k t2 =
-            let t1h = height t1 
-            let t2h = height t2
-            if  t2h > t1h + tolerance then // right is heavier than left 
-                match t2 with 
-                | SetNode(t2k,t2l,t2r,_) -> 
-                    // one of the nodes must have height > height t1 + 1 
-                    let t2lh = height t2l
-                    if t2lh > t1h + 1 then  // balance left: combination 
-                        match t2l with 
-                        | SetNode(t2lk,t2ll,t2lr,_) ->
-                            let l = mk t1 t1h k t2ll (height t2ll)
-                            let r = mk t2lr (height t2lr) t2k t2r (height t2r)
-                            mk l (height l) t2lk r (height r)
-                        | _ -> failwith "rebalance"
-                    else // rotate left 
-                        let l = mk t1 t1h k t2l t2lh
-                        mk l (height l) t2k t2r (height t2r)
-                | _ -> failwith "rebalance"
-            else
-                if  t1h > t2h + tolerance then // left is heavier than right 
-                    match t1 with 
-                    | SetNode(t1k,t1l,t1r,_) -> 
-                        // one of the nodes must have height > height t2 + 1 
-                        let t1rh = height t1r
-                        if t1rh > t2h + 1 then 
-                            // balance right: combination 
-                            match t1r with 
-                            | SetNode(t1rk,t1rl,t1rr,_) ->
-                                let l = mk t1l (height t1l) t1k t1rl (height t1rl)
-                                let r = mk t1rr (height t1rr) k t2 t2h
-                                mk l (height l) t1rk r (height r)
-                            | _ -> failwith "rebalance"
-                        else
-                            let r = mk t1r t1rh k t2 t2h
-                            mk t1l (height t1l) t1k r (height r)
-                    | _ -> failwith "rebalance"
-                else mk t1 t1h k t2 t2h
-
-        let rec add (comparer: IComparer<'T>) k t = 
-            match t with 
-            | SetNode (k2,l,r,_) -> 
-                let c = comparer.Compare(k,k2) 
-                if   c < 0 then rebalance (add comparer k l) k2 r
-                elif c = 0 then t
-                else            rebalance l k2 (add comparer k r)
-#if ONE
-            | SetOne(k2) -> 
-                // nb. no check for rebalance needed for small trees, also be sure to reuse node already allocated 
-                let c = comparer.Compare(k,k2) 
-                if c < 0   then SetNode (k,SetEmpty,t,2)
-                elif c = 0 then t
-                else            SetNode (k,t,SetEmpty,2)                  
-#endif
-            | SetEmpty -> SetOne(k)
-
-        let rec balance comparer t1 k t2 =
-            // Given t1 < k < t2 where t1 and t2 are "balanced",
-            // return a balanced tree for <t1,k,t2>.
-            // Recall: balance means subtrees heights differ by at most "tolerance"
-            match t1,t2 with
-            | SetEmpty,t2  -> add comparer k t2 // drop t1 = empty 
-            | t1,SetEmpty  -> add comparer k t1 // drop t2 = empty 
-#if ONE
-            | SetOne k1,t2 -> add comparer k (add comparer k1 t2)
-            | t1,SetOne k2 -> add comparer k (add comparer k2 t1)
-#endif
-            | SetNode(k1,t11,t12,t1h),SetNode(k2,t21,t22,t2h) ->
-                // Have:  (t11 < k1 < t12) < k < (t21 < k2 < t22)
-                // Either (a) h1,h2 differ by at most 2 - no rebalance needed.
-                //        (b) h1 too small, i.e. h1+2 < h2
-                //        (c) h2 too small, i.e. h2+2 < h1 
-                if   t1h+tolerance < t2h then
-                    // case: b, h1 too small 
-                    // push t1 into low side of t2, may increase height by 1 so rebalance 
-                    rebalance (balance comparer t1 k t21) k2 t22
-                elif t2h+tolerance < t1h then
-                    // case: c, h2 too small 
-                    // push t2 into high side of t1, may increase height by 1 so rebalance 
-                    rebalance t11 k1 (balance comparer t12 k t2)
-                else
-                    // case: a, h1 and h2 meet balance requirement 
-                    mk t1 t1h k t2 t2h
-
-        let rec split (comparer : IComparer<'T>) pivot t =
-            // Given a pivot and a set t
-            // Return { x in t s.t. x < pivot }, pivot in t? , { x in t s.t. x > pivot } 
-            match t with
-            | SetNode(k1,t11,t12,_) ->
-                let c = comparer.Compare(pivot,k1)
-                if   c < 0 then // pivot t1 
-                    let t11_lo,havePivot,t11_hi = split comparer pivot t11
-                    t11_lo,havePivot,balance comparer t11_hi k1 t12
-                elif c = 0 then // pivot is k1 
-                    t11,true,t12
-                else            // pivot t2 
-                    let t12_lo,havePivot,t12_hi = split comparer pivot t12
-                    balance comparer t11 k1 t12_lo,havePivot,t12_hi
-#if ONE
-            | SetOne k1 ->
-                let c = comparer.Compare(k1,pivot)
-                if   c < 0 then t       ,false,SetEmpty // singleton under pivot 
-                elif c = 0 then SetEmpty,true ,SetEmpty // singleton is    pivot 
-                else            SetEmpty,false,t        // singleton over  pivot 
-#endif
-            | SetEmpty  -> 
-                SetEmpty,false,SetEmpty
-        
-        let rec spliceOutSuccessor t = 
-            match t with 
-            | SetEmpty -> failwith "internal error: Map.splice_out_succ_or_pred"
-#if ONE
-            | SetOne (k2) -> k2,empty
-#endif
-            | SetNode (k2,l,r,_) ->
-                match l with 
-                | SetEmpty -> k2,r
-                | _ -> let k3,l' = spliceOutSuccessor l in k3,mk l' (height l') k2 r (height r)
-
-        let rec remove (comparer: IComparer<'T>) k t = 
-            match t with 
-            | SetEmpty -> t
-#if ONE
-            | SetOne (k2) -> 
-                let c = comparer.Compare(k,k2) 
-                if   c = 0 then empty
-                else            t
-#endif
-            | SetNode (k2,l,r,_) -> 
-                let c = comparer.Compare(k,k2) 
-                if   c < 0 then rebalance (remove comparer k l) k2 r
-                elif c = 0 then 
-                  match l,r with 
-                  | SetEmpty,_ -> r
-                  | _,SetEmpty -> l
-                  | _ -> 
-                      let sk,r' = spliceOutSuccessor r 
-                      mk l (height l) sk r' (height r')
-                else rebalance l k2 (remove comparer k r) 
-
-        let rec contains (comparer: IComparer<'T>) k t = 
-            match t with 
-            | SetNode(k2,l,r,_) -> 
-                let c = comparer.Compare(k,k2) 
-                if   c < 0 then contains comparer k l
-                elif c = 0 then true
-                else contains comparer k r
-#if ONE
-            | SetOne(k2) -> (comparer.Compare(k,k2) = 0)
-#endif
-            | SetEmpty -> false
-
-        let rec iter f t = 
-            match t with 
-            | SetNode(k2,l,r,_) -> iter f l; f k2; iter f r
-#if ONE
-            | SetOne(k2) -> f k2
-#endif
-            | SetEmpty -> ()            
-
-        // Fold, left-to-right. 
-        //
-        // NOTE: This differs from the behaviour of Map.fold which folds right-to-left.
-        let rec fold f m x = 
-            match m with 
-            | SetNode(k,l,r,_) -> fold f r (f k (fold f l x))
-#if ONE
-            | SetOne(k) -> f k x
-#endif
-            | SetEmpty -> x                
-
-        let rec forAll f m = 
-            match m with 
-            | SetNode(k2,l,r,_) -> f k2 && forAll f l && forAll f r
-#if ONE
-            | SetOne(k2) -> f k2
-#endif
-            | SetEmpty -> true          
-
-        let rec exists f m = 
-            match m with 
-            | SetNode(k2,l,r,_) -> f k2 || exists f l || exists f r
-#if ONE
-            | SetOne(k2) -> f k2
-#endif
-            | SetEmpty -> false         
-
-        let isEmpty m = match m with  | SetEmpty -> true | _ -> false
-
-        let subset comparer a b  = forAll (fun x -> contains comparer x b) a
-
-        let rec elementsAux m acc = 
-            match m with 
-            | SetNode(k2,l,r,_) -> k2 :: (elementsAux l (elementsAux r acc))
-#if ONE
-            | SetOne(k2) -> k2 :: acc
-#endif
-            | SetEmpty -> acc                
-
-        let elements a  = elementsAux a []
-
-        let rec filterAux comparer f s acc = 
-            match s with 
-            | SetNode(k,l,r,_) -> 
-                let acc = if f k then add comparer k acc else acc 
-                filterAux comparer f l (filterAux comparer f r acc)
-#if ONE
-            | SetOne(k) -> if f k then add comparer k acc else acc
-#endif
-            | SetEmpty -> acc           
-
-        let filter comparer f s = filterAux comparer f s empty
-
-        let rec diffAux comparer m acc = 
-            match m with 
-            | SetNode(k,l,r,_) -> diffAux comparer l (diffAux comparer r (remove comparer k acc))
-#if ONE
-            | SetOne(k) -> remove comparer k acc
-#endif
-            | SetEmpty -> acc           
-
-        let diff comparer a b = diffAux comparer b a
-
-        let rec countAux s acc = 
-            match s with 
-            | SetNode(_,l,r,_) -> countAux l (countAux r (acc+1))
-#if ONE
-            | SetOne(k) -> acc+1
-#endif
-            | SetEmpty -> acc           
-
-        let count s = countAux s 0
-
-        let rec union comparer t1 t2 =
-            // Perf: tried bruteForce for low heights, but nothing significant 
-            match t1,t2 with               
-            | SetNode(k1,t11,t12,h1),SetNode(k2,t21,t22,h2) -> // (t11 < k < t12) AND (t21 < k2 < t22) 
-                // Divide and Quonquer:
-                //   Suppose t1 is largest.
-                //   Split t2 using pivot k1 into lo and hi.
-                //   Union disjoint subproblems and then combine. 
-                if h1 > h2 then
-                  let lo,_,hi = split comparer k1 t2 in
-                  balance comparer (union comparer t11 lo) k1 (union comparer t12 hi)
-                else
-                  let lo,_,hi = split comparer k2 t1 in
-                  balance comparer (union comparer t21 lo) k2 (union comparer t22 hi)
-            | SetEmpty,t -> t
-            | t,SetEmpty -> t
-#if ONE
-            | SetOne k1,t2 -> add comparer k1 t2
-            | t1,SetOne k2 -> add comparer k2 t1
-#endif
-
-        let rec intersectionAux comparer b m acc = 
-            match m with 
-            | SetNode(k,l,r,_) -> 
-                let acc = intersectionAux comparer b r acc 
-                let acc = if contains comparer k b then add comparer k acc else acc 
-                intersectionAux comparer b l acc
-#if ONE
-            | SetOne(k) -> 
-                if contains comparer k b then add comparer k acc else acc
-#endif
-            | SetEmpty -> acc
-
-        let intersection comparer a b = intersectionAux comparer b a empty
-
-        let partition1 comparer f k (acc1,acc2) = 
-            if f k then (add comparer k acc1,acc2) 
-            else (acc1,add comparer k acc2) 
-        
-        let rec partitionAux comparer f s acc = 
-            match s with 
-            | SetNode(k,l,r,_) -> 
-                let acc = partitionAux comparer f r acc 
-                let acc = partition1 comparer f k acc
-                partitionAux comparer f l acc
-#if ONE
-            | SetOne(k) -> partition1 comparer f k acc
-#endif
-            | SetEmpty -> acc           
-
-        let partition comparer f s = partitionAux comparer f s (empty,empty)
-
-        // It's easier to get many less-important algorithms right using this active pattern
-        let (|MatchSetNode|MatchSetEmpty|) s = 
-            match s with 
-            | SetNode(k2,l,r,_) -> MatchSetNode(k2,l,r)
-#if ONE
-            | SetOne(k2) -> MatchSetNode(k2,SetEmpty,SetEmpty)
-#endif
-            | SetEmpty -> MatchSetEmpty
-        
-        let rec nextElemCont (comparer: IComparer<'T>) k s cont = 
-            match s with 
-            | MatchSetNode(k2,l,r) -> 
-                let c = comparer.Compare(k,k2) 
-                if   c < 0 then nextElemCont comparer k l (function None -> cont(Some(k2)) | res -> res)
-                elif c = 0 then cont(minimumElementOpt r) 
-                else nextElemCont comparer k r cont
-            | MatchSetEmpty -> cont(None)
-
-        and nextElem comparer k s = nextElemCont comparer k s (fun res -> res)
-        
-        and prevElemCont (comparer: IComparer<'T>) k s cont = 
-            match s with 
-            | MatchSetNode(k2,l,r) -> 
-                let c = comparer.Compare(k,k2) 
-                if   c > 0 then prevElemCont comparer k r (function None -> cont(Some(k2)) | res -> res)
-                elif c = 0 then cont(maximumElementOpt r) 
-                else prevElemCont comparer k l cont
-            | MatchSetEmpty -> cont(None)
-
-        and prevElem comparer k s = prevElemCont comparer k s (fun res -> res)
-        
-        and minimumElementAux s n = 
-            match s with 
-            | SetNode(k,l,_,_) -> minimumElementAux l k
-#if ONE
-            | SetOne(k) -> k
-#endif
-            | SetEmpty -> n
-
-        and minimumElementOpt s = 
-            match s with 
-            | SetNode(k,l,_,_) -> Some(minimumElementAux l k)
-#if ONE
-            | SetOne(k) -> Some k
-#endif
-            | SetEmpty -> None
-
-        and maximumElementAux s n = 
-            match s with 
-            | SetNode(k,_,r,_) -> maximumElementAux r k
-#if ONE
-            | SetOne(k) -> k
-#endif
-            | SetEmpty -> n             
-
-        and maximumElementOpt s = 
-            match s with 
-            | SetNode(k,_,r,_) -> Some(maximumElementAux r k)
-#if ONE
-            | SetOne(k) -> Some(k)
-#endif
-            | SetEmpty -> None
-
-        let minimumElement s = 
-            match minimumElementOpt s with 
-            | Some(k) -> k
-            | None -> failwith "minimumElement"            
-
-        let maximumElement s = 
-            match maximumElementOpt s with 
-            | Some(k) -> k
-            | None -> failwith "maximumElement"
-
-
-        //--------------------------------------------------------------------------
-        // Imperative left-to-right iterators.
-        //--------------------------------------------------------------------------
-
-        type SetIterator<'T>(s:SetTree<'T>) = 
-
-            // collapseLHS:
-            // a) Always returns either [] or a list starting with SetOne.
-            // b) The "fringe" of the set stack is unchanged.
-            let rec collapseLHS stack =
-                match stack with
-                | []                       -> []
-                | SetEmpty         :: rest -> collapseLHS rest
-#if ONE
-                | SetOne k         :: rest -> stack
-#else
-                | SetNode(_,SetEmpty,SetEmpty,_) :: _ -> stack
-#endif
-                | SetNode(k,l,r,_) :: rest -> collapseLHS (l :: SetOne k :: r :: rest)
-
-            // invariant: always collapseLHS result 
-            let mutable stack = collapseLHS [s]
-            // true when MoveNext has been called   
-            let mutable started = false 
-
-            let notStarted() = raise (new System.InvalidOperationException("Enumeration has not started. Call MoveNext."))
-            let alreadyFinished() = raise (new System.InvalidOperationException("Enumeration already finished."))
-
-            member i.Current =
-                if started then
-                    match stack with
-#if ONE
-                      | SetOne k :: _ -> k
-#else
-                      | SetNode( k,_,_,_) :: _ -> k
-#endif
-                      | []            -> alreadyFinished()
-                      | _             -> failwith "Please report error: Set iterator, unexpected stack for current"
-                else
-                    notStarted()
-
-            member i.MoveNext() = 
-                if started then
-                    match stack with
-#if ONE
-                      | SetOne _ :: rest -> 
-#else
-                      | SetNode _ :: rest -> 
-#endif
-                            stack <- collapseLHS rest;
-                            not stack.IsEmpty
-                      | [] -> false
-                      | _ -> failwith "Please report error: Set iterator, unexpected stack for moveNext"
-                else
-                    started <- true;  // The first call to MoveNext "starts" the enumeration.
-                    not stack.IsEmpty
-
-        let toSeq s = 
-            let i = ref (SetIterator s) 
-            { new IEnumerator<_> with 
-                  member __.Current = (!i).Current
-              interface System.Collections.IEnumerator with 
-                  member __.Current = box (!i).Current
-                  member __.MoveNext() = (!i).MoveNext()
-                  member __.Reset() = i :=  SetIterator s
-              interface System.IDisposable with 
-                  member __.Dispose() = () }
-
-        //--------------------------------------------------------------------------
-        // Set comparison.  This can be expensive.
-        //--------------------------------------------------------------------------
-
-        let rec compareStacks (comparer: IComparer<'T>) l1 l2 =
-            match l1,l2 with 
-            | [],[] ->  0
-            | [],_  -> -1
-            | _ ,[] ->  1
-            | (SetEmpty  _ :: t1),(SetEmpty    :: t2) -> compareStacks comparer t1 t2
-#if ONE
-            | (SetOne(n1k) :: t1),(SetOne(n2k) :: t2) -> 
-                 let c = comparer.Compare(n1k,n2k) 
-                 if c <> 0 then c else compareStacks comparer t1 t2
-            | (SetOne(n1k) :: t1),(SetNode(n2k,SetEmpty,n2r,_) :: t2) -> 
-                 let c = comparer.Compare(n1k,n2k) 
-                 if c <> 0 then c else compareStacks comparer (empty :: t1) (n2r :: t2)
-            | (SetNode(n1k,(SetEmpty as emp),n1r,_) :: t1),(SetOne(n2k) :: t2) -> 
-                 let c = comparer.Compare(n1k,n2k) 
-                 if c <> 0 then c else compareStacks comparer (n1r :: t1) (emp :: t2)
-#endif
-            | (SetNode(n1k,SetEmpty,n1r,_) :: t1),(SetNode(n2k,SetEmpty,n2r,_) :: t2) -> 
-                 let c = comparer.Compare(n1k,n2k) 
-                 if c <> 0 then c else compareStacks comparer (n1r :: t1) (n2r :: t2)
-#if ONE
-            | (SetOne(n1k) :: t1),_ -> 
-                compareStacks comparer (empty :: SetOne(n1k) :: t1) l2
-#endif
-            | (SetNode(n1k,n1l,n1r,_) :: t1),_ -> 
-                compareStacks comparer (n1l :: SetNode(n1k,empty,n1r,0) :: t1) l2
-#if ONE
-            | _,(SetOne(n2k) :: t2) -> 
-                compareStacks comparer l1 (empty :: SetOne(n2k) :: t2)
-#endif
-            | _,(SetNode(n2k,n2l,n2r,_) :: t2) -> 
-                compareStacks comparer l1 (n2l :: SetNode(n2k,empty,n2r,0) :: t2)
-                
-        let compare comparer s1 s2 = 
-            match s1,s2 with 
-            | SetEmpty,SetEmpty -> 0
-            | SetEmpty,_ -> -1
-            | _,SetEmpty -> 1
-            | _ -> compareStacks comparer [s1] [s2]
-
-        let choose s = minimumElement s
-
-        let toList s = 
-            let rec loop m x = 
-                match m with 
-                | SetNode(k,l,r,_) -> loop l (k :: (loop r x))
-#if ONE
-                | SetOne(k) -> k :: x
-#endif
-                | SetEmpty -> x
-            loop s []            
-
-        let copyToArray s (arr: _[]) i =
-            let j = ref i 
-            iter (fun x -> arr.[!j] <- x; j := !j + 1) s
-
-        let toArray s = 
-            let n = (count s) 
-            let res = Array.zeroCreate n 
-            copyToArray s res 0;
-            res
-
-        let rec mkFromEnumerator comparer acc (e : IEnumerator<_>) = 
-            if e.MoveNext() then 
-              mkFromEnumerator comparer (add comparer e.Current acc) e
-            else acc
-          
-        let ofSeq comparer (c : IEnumerable<_>) =
-            use ie = c.GetEnumerator()
-            mkFromEnumerator comparer empty ie 
-
-        let ofArray comparer l = Array.fold (fun acc k -> add comparer k acc) empty l    
-
-
-#if FX_NO_DEBUG_DISPLAYS
-#else
-    [<System.Diagnostics.DebuggerDisplay ("Count = {Count}")>]
-#endif
-    [<Sealed>]
-    type Set<'T,'ComparerTag> when 'ComparerTag :> IComparer<'T>(comparer: IComparer<'T>, tree: SetTree<'T>) =
-
-        static let refresh (s:Set<_,_>) t =    Set<_,_>(comparer=s.ComparerUntyped, tree=t)
-
-        member s.Tree = tree
-        member s.ComparerUntyped : IComparer<'T> = comparer 
-        member s.Comparer = (comparer :?> 'ComparerTag)
-
-        static member Empty(comparer: 'ComparerTag) : Set<'T,'ComparerTag> =  
-            Set<_,_>(comparer=comparer, tree=SetTree.empty)
-
-
-        member s.Add(x) : Set<'T,'ComparerTag> = refresh s (SetTree.add comparer x tree)
-        member s.Remove(x) : Set<'T,'ComparerTag> = refresh s (SetTree.remove comparer x tree)
-        member s.Count = SetTree.count tree
-        member s.Contains(x) = SetTree.contains comparer  x tree
-        member s.Iterate(x) = SetTree.iter  x tree
-        member s.Fold f x  = SetTree.fold f tree x
-
-#if CHECKED
-        member s.CheckBalanceInvariant = checkInvariant tree // diagnostics...
-#endif
-        member s.IsEmpty  = SetTree.isEmpty tree
-
-        member s.Partition f  : Set<'T,'ComparerTag> *  Set<'T,'ComparerTag> = 
-            match tree with 
-            | SetEmpty -> s,s
-            | _ -> 
-                let t1,t2 = SetTree.partition comparer f tree 
-                refresh s t1, refresh s t2
-
-        member s.Filter f  : Set<'T,'ComparerTag> = 
-            match tree with 
-            | SetEmpty -> s
-            | _ -> SetTree.filter comparer f tree |> refresh s
-
-        member s.Exists f = SetTree.exists f tree
-
-        member s.ForAll f = SetTree.forAll f tree
-
-        static member (-) ((a: Set<'T,'ComparerTag>),(b: Set<'T,'ComparerTag>)) = Set<_,_>.Difference(a,b)
-
-        static member (+)  ((a: Set<'T,'ComparerTag>),(b: Set<'T,'ComparerTag>)) = Set<_,_>.Union(a,b)
-
-        static member Intersection((a: Set<'T,'ComparerTag>),(b: Set<'T,'ComparerTag>)) : Set<'T,'ComparerTag>  = 
-            match b.Tree with 
-            | SetEmpty -> b  (* A INTER 0 = 0 *)
-            | _ -> 
-               match a.Tree with 
-               | SetEmpty -> a (* 0 INTER B = 0 *)
-               | _ -> SetTree.intersection a.ComparerUntyped  a.Tree b.Tree |> refresh a
-           
-        static member Union(a: Set<'T,'ComparerTag>,b: Set<'T,'ComparerTag>) : Set<'T,'ComparerTag>  = 
-            match b.Tree with 
-            | SetEmpty -> a  (* A U 0 = A *)
-            | _ -> 
-               match a.Tree with 
-               | SetEmpty -> b  (* 0 U B = B *)
-               | _ -> SetTree.union a.ComparerUntyped  a.Tree b.Tree |> refresh a
-
-        static member Difference(a: Set<'T,'ComparerTag>,b: Set<'T,'ComparerTag>) : Set<'T,'ComparerTag>  = 
-            match a.Tree with 
-            | SetEmpty -> a (* 0 - B = 0 *)
-            | _ -> 
-                match b.Tree with 
-                | SetEmpty -> a (* A - 0 = A *)
-                | _ -> SetTree.diff a.ComparerUntyped  a.Tree b.Tree |> refresh a
-
-        static member Equality(a: Set<'T,'ComparerTag>,b: Set<'T,'ComparerTag>) = 
-            (SetTree.compare a.ComparerUntyped  a.Tree b.Tree = 0)
-
-        static member Compare(a: Set<'T,'ComparerTag>,b: Set<'T,'ComparerTag>) = 
-            SetTree.compare a.ComparerUntyped  a.Tree b.Tree
-
-        member s.Choose = SetTree.choose tree
-
-        member s.MinimumElement = SetTree.minimumElement tree
-
-        member s.MaximumElement = SetTree.maximumElement tree
-
-        member s.IsSubsetOf((y: Set<'T,'ComparerTag>)) = SetTree.subset comparer tree y.Tree 
-
-        member s.IsSupersetOf((y: Set<'T,'ComparerTag>)) = SetTree.subset comparer y.Tree tree
-
-        member s.ToList () = SetTree.toList tree
-
-        member s.ToArray () = SetTree.toArray tree
-
-        override this.Equals(that) = 
-            match that with
-            // Cast to the exact same type as this, otherwise not equal.
-            | :? Set<'T,'ComparerTag> as that -> ((this :> System.IComparable).CompareTo(that) = 0)
-            | _ -> false
-
-        interface System.IComparable with
-            // Cast s2 to the exact same type as s1, see 4884.
-            // It is not OK to cast s2 to seq<'T>, since different compares could permute the elements.
-            member s1.CompareTo(s2: obj) = SetTree.compare s1.ComparerUntyped s1.Tree ((s2 :?> Set<'T,'ComparerTag>).Tree)
-
-        member this.ComputeHashCode() = 
-                let combineHash x y = (x <<< 1) + y + 631 
-                let mutable res = 0
-                for x in this do
-                    res <- combineHash res (Unchecked.hash x)
-                abs res
-
-        override this.GetHashCode() = this.ComputeHashCode()
-          
-        interface ICollection<'T> with 
-            member s.Add(x) = raise (new System.NotSupportedException("ReadOnlyCollection"))
-            member s.Clear() = raise (new System.NotSupportedException("ReadOnlyCollection"))
-            member s.Remove(x) = raise (new System.NotSupportedException("ReadOnlyCollection"))
-            member s.Contains(x) = SetTree.contains comparer x tree
-            member s.CopyTo(arr,i) = SetTree.copyToArray tree arr i
-            member s.IsReadOnly = true
-            member s.Count = SetTree.count tree  
-
-        interface IEnumerable<'T> with
-            member s.GetEnumerator() = SetTree.toSeq tree
-
-        interface System.Collections.IEnumerable with
-            override s.GetEnumerator() = (SetTree.toSeq tree :> System.Collections.IEnumerator)
-
-        static member Singleton(comparer,x) : Set<'T,'ComparerTag>  = 
-            Set<_,_>.Empty(comparer).Add(x)
-
-        static member Create(comparer : 'ComparerTag,l : seq<'T>) : Set<'T,'ComparerTag> = 
-            Set<_,_>(comparer=comparer, tree=SetTree.ofSeq comparer l)
-
-
-    [<CompilationRepresentation(CompilationRepresentationFlags.UseNullAsTrueValue)>]
-    [<NoEquality; NoComparison>]
-    type MapTree<'Key,'T> = 
-        | MapEmpty 
-#if ONE 
-        | MapOne of 'Key * 'T
-#endif
-        // Note: performance rumour has it that the data held in this node should be
-        // exactly one cache line. It is currently ~7 words. Thus it might be better to
-        // move to a n-way tree.
-        | MapNode of 'Key * 'T * MapTree<'Key,'T> *  MapTree<'Key,'T> * int
-
-
-    [<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
-    module MapTree = 
-
-        let empty = MapEmpty 
-
-        let inline height x  = 
-          match x with 
-          | MapEmpty -> 0
-#if ONE 
-          | MapOne _ -> 1
-#endif
-          | MapNode(_,_,_,_,h) -> h
-
-        let isEmpty m = 
-            match m with 
-            | MapEmpty -> true
-            | _ -> false
-
-        let mk l k v r = 
-#if ONE 
-            match l,r with 
-            | MapEmpty,MapEmpty -> MapOne(k,v)
-            | _ -> 
-#endif
-                let hl = height l 
-                let hr = height r 
-                let m = if hl < hr then hr else hl 
-                MapNode(k,v,l,r,m+1)
-
-        let rebalance t1 k v t2 =
-            let t1h = height t1 
-            if  height t2 > t1h + 2 then (* right is heavier than left *)
-                match t2 with 
-                | MapNode(t2k,t2v,t2l,t2r,_) -> 
-                   (* one of the nodes must have height > height t1 + 1 *)
-                   if height t2l > t1h + 1 then  (* balance left: combination *)
-                     match t2l with 
-                     | MapNode(t2lk,t2lv,t2ll,t2lr,_) ->
-                        mk (mk t1 k v t2ll) t2lk t2lv (mk t2lr t2k t2v t2r) 
-                     | _ -> failwith "rebalance"
-                   else (* rotate left *)
-                     mk (mk t1 k v t2l) t2k t2v t2r
-                | _ -> failwith "rebalance"
-            else
-                let t2h = height t2 
-                if  t1h > t2h + 2 then (* left is heavier than right *)
-                  match t1 with 
-                  | MapNode(t1k,t1v,t1l,t1r,_) -> 
-                    (* one of the nodes must have height > height t2 + 1 *)
-                      if height t1r > t2h + 1 then 
-                      (* balance right: combination *)
-                        match t1r with 
-                        | MapNode(t1rk,t1rv,t1rl,t1rr,_) ->
-                            mk (mk t1l t1k t1v t1rl) t1rk t1rv (mk t1rr k v t2)
-                        | _ -> failwith "rebalance"
-                      else
-                        mk t1l t1k t1v (mk t1r k v t2)
-                  | _ -> failwith "rebalance"
-                else mk t1 k v t2
-
-        let rec sizeAux acc m = 
-            match m with  
-            | MapEmpty -> acc
-#if ONE 
-            | MapOne _ -> acc + 1
-#endif
-            | MapNode(_,_,l,r,_) -> sizeAux (sizeAux (acc+1) l) r 
-
-#if ONE 
-#else
-        let MapOne(k,v) = MapNode(k,v,MapEmpty,MapEmpty,1)
-#endif
-        
-        let count x = sizeAux 0 x
-
-        let rec add (comparer: IComparer<'T>) k v m = 
-            match m with 
-            | MapEmpty -> MapOne(k,v)
-#if ONE 
-            | MapOne(k2,v2) -> 
-                let c = comparer.Compare(k,k2) 
-                if c < 0   then MapNode (k,v,MapEmpty,m,2)
-                elif c = 0 then MapOne(k,v)
-                else            MapNode (k,v,m,MapEmpty,2)
-#endif
-            | MapNode(k2,v2,l,r,h) -> 
-                let c = comparer.Compare(k,k2) 
-                if c < 0 then rebalance (add comparer k v l) k2 v2 r
-                elif c = 0 then MapNode(k,v,l,r,h)
-                else rebalance l k2 v2 (add comparer k v r) 
-
-        let indexNotFound() = raise (new System.Collections.Generic.KeyNotFoundException("An index satisfying the predicate was not found in the collection"))
-
-        let rec find (comparer: IComparer<'T>) k m = 
-            match m with 
-            | MapEmpty -> indexNotFound()
-#if ONE 
-            | MapOne(k2,v2) -> 
-                let c = comparer.Compare(k,k2) 
-                if c = 0 then v2
-                else indexNotFound()
-#endif
-            | MapNode(k2,v2,l,r,_) -> 
-                let c = comparer.Compare(k,k2) 
-                if c < 0 then find comparer k l
-                elif c = 0 then v2
-                else find comparer k r
-
-        let rec tryFind (comparer: IComparer<'T>) k m = 
-            match m with 
-            | MapEmpty -> None
-#if ONE 
-            | MapOne(k2,v2) -> 
-                let c = comparer.Compare(k,k2) 
-                if c = 0 then Some v2
-                else None
-#endif
-            | MapNode(k2,v2,l,r,_) -> 
-                let c = comparer.Compare(k,k2) 
-                if c < 0 then tryFind comparer k l
-                elif c = 0 then Some v2
-                else tryFind comparer k r
-
-        let partition1 (comparer: IComparer<'T>) f k v (acc1,acc2) = 
-            if f k v then (add comparer k v acc1,acc2) else (acc1,add comparer k v acc2) 
-        
-        let rec partitionAux (comparer: IComparer<'T>) f s acc = 
-            match s with 
-            | MapEmpty -> acc
-#if ONE 
-            | MapOne(k,v) -> partition1 comparer f k v acc
-#endif
-            | MapNode(k,v,l,r,_) -> 
-                let acc = partitionAux comparer f r acc 
-                let acc = partition1 comparer f k v acc
-                partitionAux comparer f l acc
-
-        let partition (comparer: IComparer<'T>) f s = partitionAux comparer f s (empty,empty)
-
-        let filter1 (comparer: IComparer<'T>) f k v acc = if f k v then add comparer k v acc else acc 
-
-        let rec filterAux (comparer: IComparer<'T>) f s acc = 
-            match s with 
-            | MapEmpty -> acc
-#if ONE 
-            | MapOne(k,v) -> filter1 comparer f k v acc
-#endif
-            | MapNode(k,v,l,r,_) ->
-                let acc = filterAux comparer f l acc
-                let acc = filter1 comparer f k v acc
-                filterAux comparer f r acc
-
-        let filter (comparer: IComparer<'T>) f s = filterAux comparer f s empty
-
-        let rec spliceOutSuccessor m = 
-            match m with 
-            | MapEmpty -> failwith "internal error: Map.splice_out_succ_or_pred"
-#if ONE 
-            | MapOne(k2,v2) -> k2,v2,MapEmpty
-#endif
-            | MapNode(k2,v2,l,r,_) ->
-                match l with 
-                | MapEmpty -> k2,v2,r
-                | _ -> let k3,v3,l' = spliceOutSuccessor l in k3,v3,mk l' k2 v2 r
-
-        let rec remove (comparer: IComparer<'T>) k m = 
-            match m with 
-            | MapEmpty -> empty
-#if ONE 
-            | MapOne(k2,v2) -> 
-                let c = comparer.Compare(k,k2) 
-                if c = 0 then MapEmpty else m
-#endif
-            | MapNode(k2,v2,l,r,_) -> 
-                let c = comparer.Compare(k,k2) 
-                if c < 0 then rebalance (remove comparer k l) k2 v2 r
-                elif c = 0 then 
-                  match l,r with 
-                  | MapEmpty,_ -> r
-                  | _,MapEmpty -> l
-                  | _ -> 
-                      let sk,sv,r' = spliceOutSuccessor r 
-                      mk l sk sv r'
-                else rebalance l k2 v2 (remove comparer k r) 
-
-        let rec containsKey (comparer: IComparer<'T>) k m = 
-            match m with 
-            | MapEmpty -> false
-#if ONE 
-            | MapOne(k2,v2) -> (comparer.Compare(k,k2) = 0)
-#endif
-            | MapNode(k2,_,l,r,_) -> 
-                let c = comparer.Compare(k,k2) 
-                if c < 0 then containsKey comparer k l
-                else (c = 0 || containsKey comparer k r)
-
-        let rec iter f m = 
-            match m with 
-            | MapEmpty -> ()
-#if ONE 
-            | MapOne(k2,v2) -> f k2 v2
-#endif
-            | MapNode(k2,v2,l,r,_) -> iter f l; f k2 v2; iter f r
-
-        let rec first f m = 
-            match m with 
-            | MapEmpty -> None
-#if ONE 
-            | MapOne(k2,v2) -> f k2 v2 
-#endif
-            | MapNode(k2,v2,l,r,_) -> 
-                match first f l with 
-                | Some _ as res -> res 
-                | None -> 
-                match f k2 v2 with 
-                | Some _ as res -> res 
-                | None -> first f r
-
-        let rec exists f m = 
-            match m with 
-            | MapEmpty -> false
-#if ONE 
-            | MapOne(k2,v2) -> f k2 v2
-#endif
-            | MapNode(k2,v2,l,r,_) -> f k2 v2 || exists f l || exists f r
-
-        let rec forAll f m = 
-            match m with 
-            | MapEmpty -> true
-#if ONE 
-            | MapOne(k2,v2) -> f k2 v2
-#endif
-            | MapNode(k2,v2,l,r,_) -> f k2 v2 && forAll f l && forAll f r
-
-        let rec map f m = 
-            match m with 
-            | MapEmpty -> empty
-#if ONE 
-            | MapOne(k,v) -> MapOne(k,f v)
-#endif
-            | MapNode(k,v,l,r,h) -> let v2 = f v in MapNode(k,v2,map f l, map f r,h)
-
-        let rec mapi f m = 
-            match m with
-            | MapEmpty -> empty
-#if ONE 
-            | MapOne(k,v) -> MapOne(k,f k v)
-#endif
-            | MapNode(k,v,l,r,h) -> let v2 = f k v in MapNode(k,v2, mapi f l, mapi f r,h)
-
-        // Fold, right-to-left. 
-        //
-        // NOTE: This differs from the behaviour of Set.fold which folds left-to-right.
-        let rec fold f m x = 
-            match m with 
-            | MapEmpty -> x
-#if ONE 
-            | MapOne(k,v) -> f k v x
-#endif
-            | MapNode(k,v,l,r,_) -> fold f l (f k v (fold f r x))
-
-        let foldSection (comparer: IComparer<'T>) lo hi f m x =
-            let rec fold_from_to f m x = 
-                match m with 
-                | MapEmpty -> x
-#if ONE 
-                | MapOne(k,v) ->
-                    let clo_k = comparer.Compare(lo,k)
-                    let ck_hi = comparer.Compare(k,hi)
-                    let x = if clo_k <= 0 && ck_hi <= 0 then f k v x else x
-                    x
-#endif
-                | MapNode(k,v,l,r,_) ->
-                    let clo_k = comparer.Compare(lo,k)
-                    let ck_hi = comparer.Compare(k,hi)
-                    let x = if clo_k < 0                then fold_from_to f l x else x
-                    let x = if clo_k <= 0 && ck_hi <= 0 then f k v x                     else x
-                    let x = if ck_hi < 0                then fold_from_to f r x else x
-                    x
-           
-            if comparer.Compare(lo,hi) = 1 then x else fold_from_to f m x
-
-        let rec foldMap (comparer: IComparer<'T>) f m z acc = 
-            match m with 
-            | MapEmpty -> acc,z
-#if ONE 
-            | MapOne(k,v) -> 
-                let v',z = f k v z
-                add comparer k v' acc,z
-#endif
-            | MapNode(k,v,l,r,_) -> 
-                let acc,z = foldMap comparer f r z acc
-                let v',z = f k v z
-                let acc = add comparer k v' acc 
-                foldMap comparer f l z acc
-
-        let toList m = fold (fun k v acc -> (k,v) :: acc) m []
-        let toArray m = m |> toList |> Array.ofList
-        let ofList comparer l = List.fold (fun acc (k,v) -> add comparer k v acc) empty l
-
-        
-        let rec mkFromEnumerator comparer acc (e : IEnumerator<_>) = 
-            if e.MoveNext() then 
-                let (x,y) = e.Current 
-                mkFromEnumerator comparer (add comparer x y acc) e
-            else acc
-          
-        let ofSeq comparer (c : seq<_>) =
-            use ie = c.GetEnumerator()
-            mkFromEnumerator comparer empty ie 
-          
-        let copyToArray s (arr: _[]) i =
-            let j = ref i 
-            s |> iter (fun x y -> arr.[!j] <- KeyValuePair(x,y); j := !j + 1)
-
-
-        /// Imperative left-to-right iterators.
-        type MapIterator<'Key,'T>(s:MapTree<'Key,'T>) = 
-            // collapseLHS:
-            // a) Always returns either [] or a list starting with SetOne.
-            // b) The "fringe" of the set stack is unchanged. 
-            let rec collapseLHS stack =
-                match stack with
-                | []                           -> []
-                | MapEmpty             :: rest -> collapseLHS rest
-#if ONE 
-                | MapOne _         :: _ -> stack
-#else
-                | (MapNode(_,_,MapEmpty,MapEmpty,_)) :: _ -> stack
-#endif
-                | (MapNode(k,v,l,r,_)) :: rest -> collapseLHS (l :: MapOne (k,v) :: r :: rest)
-          
-              /// invariant: always collapseLHS result 
-            let mutable stack = collapseLHS [s]
-               /// true when MoveNext has been called   
-            let mutable started = false
-
-            let notStarted() = raise (new System.InvalidOperationException("Enumeration has not started. Call MoveNext."))
-            let alreadyFinished() = raise (new System.InvalidOperationException("Enumeration already finished."))
-
-            member i.Current =
-                if started then
-                    match stack with
-#if ONE
-                      | MapOne (k,v) :: _ -> new KeyValuePair<_,_>(k,v)
-#else
-                      | (MapNode(k,v,MapEmpty,MapEmpty,_)) :: _ -> new KeyValuePair<_,_>(k,v)
-#endif
-                      | []            -> alreadyFinished()
-                      | _             -> failwith "Please report error: Map iterator, unexpected stack for current"
-                else
-                    notStarted()
-
-            member i.MoveNext() =
-              if started then
-                match stack with
-#if ONE
-                  | MapOne _ :: rest -> 
-#else
-                  | (MapNode(_,_,MapEmpty,MapEmpty,_)) :: rest -> 
-#endif
-                      stack <- collapseLHS rest;
-                      not stack.IsEmpty
-                  | [] -> false
-                  | _ -> failwith "Please report error: Map iterator, unexpected stack for moveNext"
-              else
-                  // The first call to MoveNext "starts" the enumeration. 
-                  started <- true;  
-                  not stack.IsEmpty
-
-        let toSeq s = 
-            let i = ref (MapIterator(s))
-            { new IEnumerator<_> with 
-                  member self.Current = (!i).Current
-              interface System.Collections.IEnumerator with
-                  member self.Current = box (!i).Current
-                  member self.MoveNext() = (!i).MoveNext()
-                  member self.Reset() = i :=  MapIterator(s)
-              interface System.IDisposable with 
-                  member self.Dispose() = ()}
-
-
-#if FX_NO_DEBUG_DISPLAYS
-#else
-    [<System.Diagnostics.DebuggerDisplay ("Count = {Count}")>]
-#endif
-    [<Sealed>]
-    type Map<'Key,'T,'ComparerTag> when 'ComparerTag :> IComparer<'Key>( comparer: IComparer<'Key>, tree: MapTree<'Key,'T>) =
-
-        static let refresh (m:Map<_,_,'ComparerTag>) t =    Map<_,_,'ComparerTag>(comparer=m.ComparerUntyped, tree=t)
-
-        member s.Tree = tree
-        member s.ComparerUntyped : IComparer<'Key> = comparer
-        member s.Comparer = (comparer :?> 'ComparerTag)
-
-        static member Empty(comparer : 'ComparerTag) = Map<'Key,'T,'ComparerTag>(comparer=comparer, tree=MapTree.empty)
-        member m.Add(k,v) = refresh m (MapTree.add comparer k v tree)
-        member m.IsEmpty = MapTree.isEmpty tree
-        member m.Item with get(k : 'Key) = MapTree.find comparer k tree
-        member m.First(f) = MapTree.first f tree 
-        member m.Exists(f) = MapTree.exists f tree 
-        member m.Filter(f) = MapTree.filter comparer f tree |> refresh m 
-        member m.ForAll(f) = MapTree.forAll f tree 
-        member m.Fold f acc = MapTree.fold f tree acc
-        member m.FoldSection lo hi f acc = MapTree.foldSection comparer lo hi f tree acc 
-        member m.FoldAndMap f z  = 
-            let tree,z = MapTree.foldMap comparer f tree z MapTree.empty 
-            refresh m tree, z
-        member m.Iterate f = MapTree.iter f tree
-        member m.MapRange f  = refresh m (MapTree.map f tree)
-        member m.Map f  = refresh m (MapTree.mapi f tree)
-        member m.Partition(f)  =
-            let r1,r2 = MapTree.partition comparer f tree  
-            refresh m r1, refresh m r2
-        member m.Count = MapTree.count tree
-        member m.ContainsKey(k) = MapTree.containsKey comparer k tree
-        member m.Remove(k)  = refresh m (MapTree.remove comparer k tree)
-        member m.TryFind(k) = MapTree.tryFind comparer k tree
-        member m.ToList() = MapTree.toList tree
-        member m.ToArray() = MapTree.toArray tree
-
-        static member FromList(comparer : 'ComparerTag,l) : Map<'Key,'T,'ComparerTag> = 
-            Map<_,_,_>(comparer=comparer, tree=MapTree.ofList comparer l)
-
-        static member Create(comparer : 'ComparerTag, ie : seq<_>) : Map<'Key,'T,'ComparerTag> = 
-            Map<_,_,_>(comparer=comparer, tree=MapTree.ofSeq comparer ie)
-    
-        interface IEnumerable<KeyValuePair<'Key, 'T>> with
-            member s.GetEnumerator() = MapTree.toSeq tree
-
-        interface System.Collections.IEnumerable with
-            override s.GetEnumerator() = (MapTree.toSeq tree :> System.Collections.IEnumerator)
-
-        override this.Equals(that) = 
-            match that with
-            // Cast to the exact same type as this, otherwise not equal.
-            | :? Map<'Key,'T,'ComparerTag> as that -> ((this :> System.IComparable).CompareTo(that) = 0)
-            | _ -> false
-
-        interface System.IComparable with 
-             member m1.CompareTo(m2: obj) = 
-                 Seq.compareWith 
-                   (fun (kvp1 : KeyValuePair<_,_>) (kvp2 : KeyValuePair<_,_>)-> 
-                       let c = m1.ComparerUntyped.Compare(kvp1.Key,kvp2.Key) in 
-                       if c <> 0 then c else Unchecked.compare kvp1.Value kvp2.Value)
-                   // Cast m2 to the exact same type as m1, see 4884.
-                   // It is not OK to cast m2 to seq<KeyValuePair<'Key,'T>>, since different compares could permute the KVPs.
-                   m1 (m2 :?> Map<'Key,'T,'ComparerTag>)
-
-        member this.ComputeHashCode() = 
-            let combineHash x y = (x <<< 1) + y + 631 
-            let mutable res = 0
-            for KeyValue(x,y) in this do
-                res <- combineHash res (Unchecked.hash x)
-                res <- combineHash res (Unchecked.hash y)
-            abs res
-
-        override this.GetHashCode() = this.ComputeHashCode()
-
-
-    type Map<'Key,'T> = Map<'Key, 'T, IComparer<'Key>>    
-    type Set<'T> = Set<'T, IComparer<'T>>    
-
+// (c) Microsoft Corporation 2005-2009. 
+
+
+namespace Microsoft.FSharp.Collections.Tagged
+
+    #nowarn "51"
+    #nowarn "69" // interface implementations in augmentations
+    #nowarn "60" // override implementations in augmentations
+
+    open System
+    open System.Collections.Generic
+    open Microsoft.FSharp.Collections
+
+    [<CompilationRepresentation(CompilationRepresentationFlags.UseNullAsTrueValue)>]
+    [<NoEquality; NoComparison>]
+    type SetTree<'T> = 
+        | SetEmpty                                          // height = 0   
+        | SetNode of 'T * SetTree<'T> *  SetTree<'T> * int    // height = int 
+#if ONE
+        | SetOne  of 'T                                     // height = 1   
+#endif
+        // OPTIMIZATION: store SetNode(k,SetEmpty,SetEmpty,1) --->  SetOne(k) 
+
+
+    // CONSIDER: SetTree<'T> = SetEmpty | SetNode of 'T  * SetTree<'T> *  SetTree<'T> * int
+    //  with SetOne = SetNode of (x,null,null,1)
+
+    [<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+    module SetTree = 
+        let empty = SetEmpty
+
+        let height t = 
+            match t with 
+            | SetEmpty -> 0
+#if ONE
+            | SetOne _ -> 1
+#endif
+            | SetNode (_,_,_,h) -> h
+
+#if CHECKED
+        let rec checkInvariant t =
+            // A good sanity check, loss of balance can hit perf 
+            match t with 
+            | SetEmpty -> true
+            | SetOne _ -> true
+            | SetNode (k,t1,t2,h) ->
+                let h1 = height t1 in
+                let h2 = height t2 in
+                (-2 <= (h1 - h2) && (h1 - h2) <= 2) && checkInvariant t1 && checkInvariant t2
+#else
+        let inline SetOne(x) = SetNode(x,SetEmpty,SetEmpty,1)
+#endif
+
+        let tolerance = 2
+
+        let mk l hl k r hr = 
+#if ONE
+            if hl = 0 && hr = 0 then SetOne (k)
+            else
+#endif
+              let m = if hl < hr then hr else hl 
+              SetNode(k,l,r,m+1)
+
+        let rebalance t1 k t2 =
+            let t1h = height t1 
+            let t2h = height t2
+            if  t2h > t1h + tolerance then // right is heavier than left 
+                match t2 with 
+                | SetNode(t2k,t2l,t2r,_) -> 
+                    // one of the nodes must have height > height t1 + 1 
+                    let t2lh = height t2l
+                    if t2lh > t1h + 1 then  // balance left: combination 
+                        match t2l with 
+                        | SetNode(t2lk,t2ll,t2lr,_) ->
+                            let l = mk t1 t1h k t2ll (height t2ll)
+                            let r = mk t2lr (height t2lr) t2k t2r (height t2r)
+                            mk l (height l) t2lk r (height r)
+                        | _ -> failwith "rebalance"
+                    else // rotate left 
+                        let l = mk t1 t1h k t2l t2lh
+                        mk l (height l) t2k t2r (height t2r)
+                | _ -> failwith "rebalance"
+            else
+                if  t1h > t2h + tolerance then // left is heavier than right 
+                    match t1 with 
+                    | SetNode(t1k,t1l,t1r,_) -> 
+                        // one of the nodes must have height > height t2 + 1 
+                        let t1rh = height t1r
+                        if t1rh > t2h + 1 then 
+                            // balance right: combination 
+                            match t1r with 
+                            | SetNode(t1rk,t1rl,t1rr,_) ->
+                                let l = mk t1l (height t1l) t1k t1rl (height t1rl)
+                                let r = mk t1rr (height t1rr) k t2 t2h
+                                mk l (height l) t1rk r (height r)
+                            | _ -> failwith "rebalance"
+                        else
+                            let r = mk t1r t1rh k t2 t2h
+                            mk t1l (height t1l) t1k r (height r)
+                    | _ -> failwith "rebalance"
+                else mk t1 t1h k t2 t2h
+
+        let rec add (comparer: IComparer<'T>) k t = 
+            match t with 
+            | SetNode (k2,l,r,_) -> 
+                let c = comparer.Compare(k,k2) 
+                if   c < 0 then rebalance (add comparer k l) k2 r
+                elif c = 0 then t
+                else            rebalance l k2 (add comparer k r)
+#if ONE
+            | SetOne(k2) -> 
+                // nb. no check for rebalance needed for small trees, also be sure to reuse node already allocated 
+                let c = comparer.Compare(k,k2) 
+                if c < 0   then SetNode (k,SetEmpty,t,2)
+                elif c = 0 then t
+                else            SetNode (k,t,SetEmpty,2)                  
+#endif
+            | SetEmpty -> SetOne(k)
+
+        let rec balance comparer t1 k t2 =
+            // Given t1 < k < t2 where t1 and t2 are "balanced",
+            // return a balanced tree for <t1,k,t2>.
+            // Recall: balance means subtrees heights differ by at most "tolerance"
+            match t1,t2 with
+            | SetEmpty,t2  -> add comparer k t2 // drop t1 = empty 
+            | t1,SetEmpty  -> add comparer k t1 // drop t2 = empty 
+#if ONE
+            | SetOne k1,t2 -> add comparer k (add comparer k1 t2)
+            | t1,SetOne k2 -> add comparer k (add comparer k2 t1)
+#endif
+            | SetNode(k1,t11,t12,t1h),SetNode(k2,t21,t22,t2h) ->
+                // Have:  (t11 < k1 < t12) < k < (t21 < k2 < t22)
+                // Either (a) h1,h2 differ by at most 2 - no rebalance needed.
+                //        (b) h1 too small, i.e. h1+2 < h2
+                //        (c) h2 too small, i.e. h2+2 < h1 
+                if   t1h+tolerance < t2h then
+                    // case: b, h1 too small 
+                    // push t1 into low side of t2, may increase height by 1 so rebalance 
+                    rebalance (balance comparer t1 k t21) k2 t22
+                elif t2h+tolerance < t1h then
+                    // case: c, h2 too small 
+                    // push t2 into high side of t1, may increase height by 1 so rebalance 
+                    rebalance t11 k1 (balance comparer t12 k t2)
+                else
+                    // case: a, h1 and h2 meet balance requirement 
+                    mk t1 t1h k t2 t2h
+
+        let rec split (comparer : IComparer<'T>) pivot t =
+            // Given a pivot and a set t
+            // Return { x in t s.t. x < pivot }, pivot in t? , { x in t s.t. x > pivot } 
+            match t with
+            | SetNode(k1,t11,t12,_) ->
+                let c = comparer.Compare(pivot,k1)
+                if   c < 0 then // pivot t1 
+                    let t11_lo,havePivot,t11_hi = split comparer pivot t11
+                    t11_lo,havePivot,balance comparer t11_hi k1 t12
+                elif c = 0 then // pivot is k1 
+                    t11,true,t12
+                else            // pivot t2 
+                    let t12_lo,havePivot,t12_hi = split comparer pivot t12
+                    balance comparer t11 k1 t12_lo,havePivot,t12_hi
+#if ONE
+            | SetOne k1 ->
+                let c = comparer.Compare(k1,pivot)
+                if   c < 0 then t       ,false,SetEmpty // singleton under pivot 
+                elif c = 0 then SetEmpty,true ,SetEmpty // singleton is    pivot 
+                else            SetEmpty,false,t        // singleton over  pivot 
+#endif
+            | SetEmpty  -> 
+                SetEmpty,false,SetEmpty
+        
+        let rec spliceOutSuccessor t = 
+            match t with 
+            | SetEmpty -> failwith "internal error: Map.splice_out_succ_or_pred"
+#if ONE
+            | SetOne (k2) -> k2,empty
+#endif
+            | SetNode (k2,l,r,_) ->
+                match l with 
+                | SetEmpty -> k2,r
+                | _ -> let k3,l' = spliceOutSuccessor l in k3,mk l' (height l') k2 r (height r)
+
+        let rec remove (comparer: IComparer<'T>) k t = 
+            match t with 
+            | SetEmpty -> t
+#if ONE
+            | SetOne (k2) -> 
+                let c = comparer.Compare(k,k2) 
+                if   c = 0 then empty
+                else            t
+#endif
+            | SetNode (k2,l,r,_) -> 
+                let c = comparer.Compare(k,k2) 
+                if   c < 0 then rebalance (remove comparer k l) k2 r
+                elif c = 0 then 
+                  match l,r with 
+                  | SetEmpty,_ -> r
+                  | _,SetEmpty -> l
+                  | _ -> 
+                      let sk,r' = spliceOutSuccessor r 
+                      mk l (height l) sk r' (height r')
+                else rebalance l k2 (remove comparer k r) 
+
+        let rec contains (comparer: IComparer<'T>) k t = 
+            match t with 
+            | SetNode(k2,l,r,_) -> 
+                let c = comparer.Compare(k,k2) 
+                if   c < 0 then contains comparer k l
+                elif c = 0 then true
+                else contains comparer k r
+#if ONE
+            | SetOne(k2) -> (comparer.Compare(k,k2) = 0)
+#endif
+            | SetEmpty -> false
+
+        let rec iter f t = 
+            match t with 
+            | SetNode(k2,l,r,_) -> iter f l; f k2; iter f r
+#if ONE
+            | SetOne(k2) -> f k2
+#endif
+            | SetEmpty -> ()            
+
+        // Fold, left-to-right. 
+        //
+        // NOTE: This differs from the behaviour of Map.fold which folds right-to-left.
+        let rec fold f m x = 
+            match m with 
+            | SetNode(k,l,r,_) -> fold f r (f k (fold f l x))
+#if ONE
+            | SetOne(k) -> f k x
+#endif
+            | SetEmpty -> x                
+
+        let rec forAll f m = 
+            match m with 
+            | SetNode(k2,l,r,_) -> f k2 && forAll f l && forAll f r
+#if ONE
+            | SetOne(k2) -> f k2
+#endif
+            | SetEmpty -> true          
+
+        let rec exists f m = 
+            match m with 
+            | SetNode(k2,l,r,_) -> f k2 || exists f l || exists f r
+#if ONE
+            | SetOne(k2) -> f k2
+#endif
+            | SetEmpty -> false         
+
+        let isEmpty m = match m with  | SetEmpty -> true | _ -> false
+
+        let subset comparer a b  = forAll (fun x -> contains comparer x b) a
+
+        let rec elementsAux m acc = 
+            match m with 
+            | SetNode(k2,l,r,_) -> k2 :: (elementsAux l (elementsAux r acc))
+#if ONE
+            | SetOne(k2) -> k2 :: acc
+#endif
+            | SetEmpty -> acc                
+
+        let elements a  = elementsAux a []
+
+        let rec filterAux comparer f s acc = 
+            match s with 
+            | SetNode(k,l,r,_) -> 
+                let acc = if f k then add comparer k acc else acc 
+                filterAux comparer f l (filterAux comparer f r acc)
+#if ONE
+            | SetOne(k) -> if f k then add comparer k acc else acc
+#endif
+            | SetEmpty -> acc           
+
+        let filter comparer f s = filterAux comparer f s empty
+
+        let rec diffAux comparer m acc = 
+            match m with 
+            | SetNode(k,l,r,_) -> diffAux comparer l (diffAux comparer r (remove comparer k acc))
+#if ONE
+            | SetOne(k) -> remove comparer k acc
+#endif
+            | SetEmpty -> acc           
+
+        let diff comparer a b = diffAux comparer b a
+
+        let rec countAux s acc = 
+            match s with 
+            | SetNode(_,l,r,_) -> countAux l (countAux r (acc+1))
+#if ONE
+            | SetOne(k) -> acc+1
+#endif
+            | SetEmpty -> acc           
+
+        let count s = countAux s 0
+
+        let rec union comparer t1 t2 =
+            // Perf: tried bruteForce for low heights, but nothing significant 
+            match t1,t2 with               
+            | SetNode(k1,t11,t12,h1),SetNode(k2,t21,t22,h2) -> // (t11 < k < t12) AND (t21 < k2 < t22) 
+                // Divide and Quonquer:
+                //   Suppose t1 is largest.
+                //   Split t2 using pivot k1 into lo and hi.
+                //   Union disjoint subproblems and then combine. 
+                if h1 > h2 then
+                  let lo,_,hi = split comparer k1 t2 in
+                  balance comparer (union comparer t11 lo) k1 (union comparer t12 hi)
+                else
+                  let lo,_,hi = split comparer k2 t1 in
+                  balance comparer (union comparer t21 lo) k2 (union comparer t22 hi)
+            | SetEmpty,t -> t
+            | t,SetEmpty -> t
+#if ONE
+            | SetOne k1,t2 -> add comparer k1 t2
+            | t1,SetOne k2 -> add comparer k2 t1
+#endif
+
+        let rec intersectionAux comparer b m acc = 
+            match m with 
+            | SetNode(k,l,r,_) -> 
+                let acc = intersectionAux comparer b r acc 
+                let acc = if contains comparer k b then add comparer k acc else acc 
+                intersectionAux comparer b l acc
+#if ONE
+            | SetOne(k) -> 
+                if contains comparer k b then add comparer k acc else acc
+#endif
+            | SetEmpty -> acc
+
+        let intersection comparer a b = intersectionAux comparer b a empty
+
+        let partition1 comparer f k (acc1,acc2) = 
+            if f k then (add comparer k acc1,acc2) 
+            else (acc1,add comparer k acc2) 
+        
+        let rec partitionAux comparer f s acc = 
+            match s with 
+            | SetNode(k,l,r,_) -> 
+                let acc = partitionAux comparer f r acc 
+                let acc = partition1 comparer f k acc
+                partitionAux comparer f l acc
+#if ONE
+            | SetOne(k) -> partition1 comparer f k acc
+#endif
+            | SetEmpty -> acc           
+
+        let partition comparer f s = partitionAux comparer f s (empty,empty)
+
+        // It's easier to get many less-important algorithms right using this active pattern
+        let (|MatchSetNode|MatchSetEmpty|) s = 
+            match s with 
+            | SetNode(k2,l,r,_) -> MatchSetNode(k2,l,r)
+#if ONE
+            | SetOne(k2) -> MatchSetNode(k2,SetEmpty,SetEmpty)
+#endif
+            | SetEmpty -> MatchSetEmpty
+        
+        let rec nextElemCont (comparer: IComparer<'T>) k s cont = 
+            match s with 
+            | MatchSetNode(k2,l,r) -> 
+                let c = comparer.Compare(k,k2) 
+                if   c < 0 then nextElemCont comparer k l (function None -> cont(Some(k2)) | res -> res)
+                elif c = 0 then cont(minimumElementOpt r) 
+                else nextElemCont comparer k r cont
+            | MatchSetEmpty -> cont(None)
+
+        and nextElem comparer k s = nextElemCont comparer k s (fun res -> res)
+        
+        and prevElemCont (comparer: IComparer<'T>) k s cont = 
+            match s with 
+            | MatchSetNode(k2,l,r) -> 
+                let c = comparer.Compare(k,k2) 
+                if   c > 0 then prevElemCont comparer k r (function None -> cont(Some(k2)) | res -> res)
+                elif c = 0 then cont(maximumElementOpt r) 
+                else prevElemCont comparer k l cont
+            | MatchSetEmpty -> cont(None)
+
+        and prevElem comparer k s = prevElemCont comparer k s (fun res -> res)
+        
+        and minimumElementAux s n = 
+            match s with 
+            | SetNode(k,l,_,_) -> minimumElementAux l k
+#if ONE
+            | SetOne(k) -> k
+#endif
+            | SetEmpty -> n
+
+        and minimumElementOpt s = 
+            match s with 
+            | SetNode(k,l,_,_) -> Some(minimumElementAux l k)
+#if ONE
+            | SetOne(k) -> Some k
+#endif
+            | SetEmpty -> None
+
+        and maximumElementAux s n = 
+            match s with 
+            | SetNode(k,_,r,_) -> maximumElementAux r k
+#if ONE
+            | SetOne(k) -> k
+#endif
+            | SetEmpty -> n             
+
+        and maximumElementOpt s = 
+            match s with 
+            | SetNode(k,_,r,_) -> Some(maximumElementAux r k)
+#if ONE
+            | SetOne(k) -> Some(k)
+#endif
+            | SetEmpty -> None
+
+        let minimumElement s = 
+            match minimumElementOpt s with 
+            | Some(k) -> k
+            | None -> failwith "minimumElement"            
+
+        let maximumElement s = 
+            match maximumElementOpt s with 
+            | Some(k) -> k
+            | None -> failwith "maximumElement"
+
+
+        //--------------------------------------------------------------------------
+        // Imperative left-to-right iterators.
+        //--------------------------------------------------------------------------
+
+        type SetIterator<'T>(s:SetTree<'T>) = 
+
+            // collapseLHS:
+            // a) Always returns either [] or a list starting with SetOne.
+            // b) The "fringe" of the set stack is unchanged.
+            let rec collapseLHS stack =
+                match stack with
+                | []                       -> []
+                | SetEmpty         :: rest -> collapseLHS rest
+#if ONE
+                | SetOne k         :: rest -> stack
+#else
+                | SetNode(_,SetEmpty,SetEmpty,_) :: _ -> stack
+#endif
+                | SetNode(k,l,r,_) :: rest -> collapseLHS (l :: SetOne k :: r :: rest)
+
+            // invariant: always collapseLHS result 
+            let mutable stack = collapseLHS [s]
+            // true when MoveNext has been called   
+            let mutable started = false 
+
+            let notStarted() = raise (new System.InvalidOperationException("Enumeration has not started. Call MoveNext."))
+            let alreadyFinished() = raise (new System.InvalidOperationException("Enumeration already finished."))
+
+            member i.Current =
+                if started then
+                    match stack with
+#if ONE
+                      | SetOne k :: _ -> k
+#else
+                      | SetNode( k,_,_,_) :: _ -> k
+#endif
+                      | []            -> alreadyFinished()
+                      | _             -> failwith "Please report error: Set iterator, unexpected stack for current"
+                else
+                    notStarted()
+
+            member i.MoveNext() = 
+                if started then
+                    match stack with
+#if ONE
+                      | SetOne _ :: rest -> 
+#else
+                      | SetNode _ :: rest -> 
+#endif
+                            stack <- collapseLHS rest;
+                            not stack.IsEmpty
+                      | [] -> false
+                      | _ -> failwith "Please report error: Set iterator, unexpected stack for moveNext"
+                else
+                    started <- true;  // The first call to MoveNext "starts" the enumeration.
+                    not stack.IsEmpty
+
+        let toSeq s = 
+            let i = ref (SetIterator s) 
+            { new IEnumerator<_> with 
+                  member __.Current = (!i).Current
+              interface System.Collections.IEnumerator with 
+                  member __.Current = box (!i).Current
+                  member __.MoveNext() = (!i).MoveNext()
+                  member __.Reset() = i :=  SetIterator s
+              interface System.IDisposable with 
+                  member __.Dispose() = () }
+
+        //--------------------------------------------------------------------------
+        // Set comparison.  This can be expensive.
+        //--------------------------------------------------------------------------
+
+        let rec compareStacks (comparer: IComparer<'T>) l1 l2 =
+            match l1,l2 with 
+            | [],[] ->  0
+            | [],_  -> -1
+            | _ ,[] ->  1
+            | (SetEmpty  _ :: t1),(SetEmpty    :: t2) -> compareStacks comparer t1 t2
+#if ONE
+            | (SetOne(n1k) :: t1),(SetOne(n2k) :: t2) -> 
+                 let c = comparer.Compare(n1k,n2k) 
+                 if c <> 0 then c else compareStacks comparer t1 t2
+            | (SetOne(n1k) :: t1),(SetNode(n2k,SetEmpty,n2r,_) :: t2) -> 
+                 let c = comparer.Compare(n1k,n2k) 
+                 if c <> 0 then c else compareStacks comparer (empty :: t1) (n2r :: t2)
+            | (SetNode(n1k,(SetEmpty as emp),n1r,_) :: t1),(SetOne(n2k) :: t2) -> 
+                 let c = comparer.Compare(n1k,n2k) 
+                 if c <> 0 then c else compareStacks comparer (n1r :: t1) (emp :: t2)
+#endif
+            | (SetNode(n1k,SetEmpty,n1r,_) :: t1),(SetNode(n2k,SetEmpty,n2r,_) :: t2) -> 
+                 let c = comparer.Compare(n1k,n2k) 
+                 if c <> 0 then c else compareStacks comparer (n1r :: t1) (n2r :: t2)
+#if ONE
+            | (SetOne(n1k) :: t1),_ -> 
+                compareStacks comparer (empty :: SetOne(n1k) :: t1) l2
+#endif
+            | (SetNode(n1k,n1l,n1r,_) :: t1),_ -> 
+                compareStacks comparer (n1l :: SetNode(n1k,empty,n1r,0) :: t1) l2
+#if ONE
+            | _,(SetOne(n2k) :: t2) -> 
+                compareStacks comparer l1 (empty :: SetOne(n2k) :: t2)
+#endif
+            | _,(SetNode(n2k,n2l,n2r,_) :: t2) -> 
+                compareStacks comparer l1 (n2l :: SetNode(n2k,empty,n2r,0) :: t2)
+                
+        let compare comparer s1 s2 = 
+            match s1,s2 with 
+            | SetEmpty,SetEmpty -> 0
+            | SetEmpty,_ -> -1
+            | _,SetEmpty -> 1
+            | _ -> compareStacks comparer [s1] [s2]
+
+        let choose s = minimumElement s
+
+        let toList s = 
+            let rec loop m x = 
+                match m with 
+                | SetNode(k,l,r,_) -> loop l (k :: (loop r x))
+#if ONE
+                | SetOne(k) -> k :: x
+#endif
+                | SetEmpty -> x
+            loop s []            
+
+        let copyToArray s (arr: _[]) i =
+            let j = ref i 
+            iter (fun x -> arr.[!j] <- x; j := !j + 1) s
+
+        let toArray s = 
+            let n = (count s) 
+            let res = Array.zeroCreate n 
+            copyToArray s res 0;
+            res
+
+        let rec mkFromEnumerator comparer acc (e : IEnumerator<_>) = 
+            if e.MoveNext() then 
+              mkFromEnumerator comparer (add comparer e.Current acc) e
+            else acc
+          
+        let ofSeq comparer (c : IEnumerable<_>) =
+            use ie = c.GetEnumerator()
+            mkFromEnumerator comparer empty ie 
+
+        let ofArray comparer l = Array.fold (fun acc k -> add comparer k acc) empty l    
+
+
+#if FX_NO_DEBUG_DISPLAYS
+#else
+    [<System.Diagnostics.DebuggerDisplay ("Count = {Count}")>]
+#endif
+    [<Sealed>]
+    type Set<'T,'ComparerTag> when 'ComparerTag :> IComparer<'T>(comparer: IComparer<'T>, tree: SetTree<'T>) =
+
+        static let refresh (s:Set<_,_>) t =    Set<_,_>(comparer=s.ComparerUntyped, tree=t)
+
+        member s.Tree = tree
+        member s.ComparerUntyped : IComparer<'T> = comparer 
+        member s.Comparer = (comparer :?> 'ComparerTag)
+
+        static member Empty(comparer: 'ComparerTag) : Set<'T,'ComparerTag> =  
+            Set<_,_>(comparer=comparer, tree=SetTree.empty)
+
+
+        member s.Add(x) : Set<'T,'ComparerTag> = refresh s (SetTree.add comparer x tree)
+        member s.Remove(x) : Set<'T,'ComparerTag> = refresh s (SetTree.remove comparer x tree)
+        member s.Count = SetTree.count tree
+        member s.Contains(x) = SetTree.contains comparer  x tree
+        member s.Iterate(x) = SetTree.iter  x tree
+        member s.Fold f x  = SetTree.fold f tree x
+
+#if CHECKED
+        member s.CheckBalanceInvariant = checkInvariant tree // diagnostics...
+#endif
+        member s.IsEmpty  = SetTree.isEmpty tree
+
+        member s.Partition f  : Set<'T,'ComparerTag> *  Set<'T,'ComparerTag> = 
+            match tree with 
+            | SetEmpty -> s,s
+            | _ -> 
+                let t1,t2 = SetTree.partition comparer f tree 
+                refresh s t1, refresh s t2
+
+        member s.Filter f  : Set<'T,'ComparerTag> = 
+            match tree with 
+            | SetEmpty -> s
+            | _ -> SetTree.filter comparer f tree |> refresh s
+
+        member s.Exists f = SetTree.exists f tree
+
+        member s.ForAll f = SetTree.forAll f tree
+
+        static member (-) ((a: Set<'T,'ComparerTag>),(b: Set<'T,'ComparerTag>)) = Set<_,_>.Difference(a,b)
+
+        static member (+)  ((a: Set<'T,'ComparerTag>),(b: Set<'T,'ComparerTag>)) = Set<_,_>.Union(a,b)
+
+        static member Intersection((a: Set<'T,'ComparerTag>),(b: Set<'T,'ComparerTag>)) : Set<'T,'ComparerTag>  = 
+            match b.Tree with 
+            | SetEmpty -> b  (* A INTER 0 = 0 *)
+            | _ -> 
+               match a.Tree with 
+               | SetEmpty -> a (* 0 INTER B = 0 *)
+               | _ -> SetTree.intersection a.ComparerUntyped  a.Tree b.Tree |> refresh a
+           
+        static member Union(a: Set<'T,'ComparerTag>,b: Set<'T,'ComparerTag>) : Set<'T,'ComparerTag>  = 
+            match b.Tree with 
+            | SetEmpty -> a  (* A U 0 = A *)
+            | _ -> 
+               match a.Tree with 
+               | SetEmpty -> b  (* 0 U B = B *)
+               | _ -> SetTree.union a.ComparerUntyped  a.Tree b.Tree |> refresh a
+
+        static member Difference(a: Set<'T,'ComparerTag>,b: Set<'T,'ComparerTag>) : Set<'T,'ComparerTag>  = 
+            match a.Tree with 
+            | SetEmpty -> a (* 0 - B = 0 *)
+            | _ -> 
+                match b.Tree with 
+                | SetEmpty -> a (* A - 0 = A *)
+                | _ -> SetTree.diff a.ComparerUntyped  a.Tree b.Tree |> refresh a
+
+        static member Equality(a: Set<'T,'ComparerTag>,b: Set<'T,'ComparerTag>) = 
+            (SetTree.compare a.ComparerUntyped  a.Tree b.Tree = 0)
+
+        static member Compare(a: Set<'T,'ComparerTag>,b: Set<'T,'ComparerTag>) = 
+            SetTree.compare a.ComparerUntyped  a.Tree b.Tree
+
+        member s.Choose = SetTree.choose tree
+
+        member s.MinimumElement = SetTree.minimumElement tree
+
+        member s.MaximumElement = SetTree.maximumElement tree
+
+        member s.IsSubsetOf((y: Set<'T,'ComparerTag>)) = SetTree.subset comparer tree y.Tree 
+
+        member s.IsSupersetOf((y: Set<'T,'ComparerTag>)) = SetTree.subset comparer y.Tree tree
+
+        member s.ToList () = SetTree.toList tree
+
+        member s.ToArray () = SetTree.toArray tree
+
+        override this.Equals(that) = 
+            match that with
+            // Cast to the exact same type as this, otherwise not equal.
+            | :? Set<'T,'ComparerTag> as that -> ((this :> System.IComparable).CompareTo(that) = 0)
+            | _ -> false
+
+        interface System.IComparable with
+            // Cast s2 to the exact same type as s1, see 4884.
+            // It is not OK to cast s2 to seq<'T>, since different compares could permute the elements.
+            member s1.CompareTo(s2: obj) = SetTree.compare s1.ComparerUntyped s1.Tree ((s2 :?> Set<'T,'ComparerTag>).Tree)
+
+        member this.ComputeHashCode() = 
+                let combineHash x y = (x <<< 1) + y + 631 
+                let mutable res = 0
+                for x in this do
+                    res <- combineHash res (Unchecked.hash x)
+                abs res
+
+        override this.GetHashCode() = this.ComputeHashCode()
+          
+        interface ICollection<'T> with 
+            member s.Add(x) = raise (new System.NotSupportedException("ReadOnlyCollection"))
+            member s.Clear() = raise (new System.NotSupportedException("ReadOnlyCollection"))
+            member s.Remove(x) = raise (new System.NotSupportedException("ReadOnlyCollection"))
+            member s.Contains(x) = SetTree.contains comparer x tree
+            member s.CopyTo(arr,i) = SetTree.copyToArray tree arr i
+            member s.IsReadOnly = true
+            member s.Count = SetTree.count tree  
+
+        interface IEnumerable<'T> with
+            member s.GetEnumerator() = SetTree.toSeq tree
+
+        interface System.Collections.IEnumerable with
+            override s.GetEnumerator() = (SetTree.toSeq tree :> System.Collections.IEnumerator)
+
+        static member Singleton(comparer,x) : Set<'T,'ComparerTag>  = 
+            Set<_,_>.Empty(comparer).Add(x)
+
+        static member Create(comparer : 'ComparerTag,l : seq<'T>) : Set<'T,'ComparerTag> = 
+            Set<_,_>(comparer=comparer, tree=SetTree.ofSeq comparer l)
+
+
+    [<CompilationRepresentation(CompilationRepresentationFlags.UseNullAsTrueValue)>]
+    [<NoEquality; NoComparison>]
+    type MapTree<'Key,'T> = 
+        | MapEmpty 
+#if ONE 
+        | MapOne of 'Key * 'T
+#endif
+        // Note: performance rumour has it that the data held in this node should be
+        // exactly one cache line. It is currently ~7 words. Thus it might be better to
+        // move to a n-way tree.
+        | MapNode of 'Key * 'T * MapTree<'Key,'T> *  MapTree<'Key,'T> * int
+
+
+    [<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+    module MapTree = 
+
+        let empty = MapEmpty 
+
+        let inline height x  = 
+          match x with 
+          | MapEmpty -> 0
+#if ONE 
+          | MapOne _ -> 1
+#endif
+          | MapNode(_,_,_,_,h) -> h
+
+        let isEmpty m = 
+            match m with 
+            | MapEmpty -> true
+            | _ -> false
+
+        let mk l k v r = 
+#if ONE 
+            match l,r with 
+            | MapEmpty,MapEmpty -> MapOne(k,v)
+            | _ -> 
+#endif
+                let hl = height l 
+                let hr = height r 
+                let m = if hl < hr then hr else hl 
+                MapNode(k,v,l,r,m+1)
+
+        let rebalance t1 k v t2 =
+            let t1h = height t1 
+            if  height t2 > t1h + 2 then (* right is heavier than left *)
+                match t2 with 
+                | MapNode(t2k,t2v,t2l,t2r,_) -> 
+                   (* one of the nodes must have height > height t1 + 1 *)
+                   if height t2l > t1h + 1 then  (* balance left: combination *)
+                     match t2l with 
+                     | MapNode(t2lk,t2lv,t2ll,t2lr,_) ->
+                        mk (mk t1 k v t2ll) t2lk t2lv (mk t2lr t2k t2v t2r) 
+                     | _ -> failwith "rebalance"
+                   else (* rotate left *)
+                     mk (mk t1 k v t2l) t2k t2v t2r
+                | _ -> failwith "rebalance"
+            else
+                let t2h = height t2 
+                if  t1h > t2h + 2 then (* left is heavier than right *)
+                  match t1 with 
+                  | MapNode(t1k,t1v,t1l,t1r,_) -> 
+                    (* one of the nodes must have height > height t2 + 1 *)
+                      if height t1r > t2h + 1 then 
+                      (* balance right: combination *)
+                        match t1r with 
+                        | MapNode(t1rk,t1rv,t1rl,t1rr,_) ->
+                            mk (mk t1l t1k t1v t1rl) t1rk t1rv (mk t1rr k v t2)
+                        | _ -> failwith "rebalance"
+                      else
+                        mk t1l t1k t1v (mk t1r k v t2)
+                  | _ -> failwith "rebalance"
+                else mk t1 k v t2
+
+        let rec sizeAux acc m = 
+            match m with  
+            | MapEmpty -> acc
+#if ONE 
+            | MapOne _ -> acc + 1
+#endif
+            | MapNode(_,_,l,r,_) -> sizeAux (sizeAux (acc+1) l) r 
+
+#if ONE 
+#else
+        let MapOne(k,v) = MapNode(k,v,MapEmpty,MapEmpty,1)
+#endif
+        
+        let count x = sizeAux 0 x
+
+        let rec add (comparer: IComparer<'T>) k v m = 
+            match m with 
+            | MapEmpty -> MapOne(k,v)
+#if ONE 
+            | MapOne(k2,v2) -> 
+                let c = comparer.Compare(k,k2) 
+                if c < 0   then MapNode (k,v,MapEmpty,m,2)
+                elif c = 0 then MapOne(k,v)
+                else            MapNode (k,v,m,MapEmpty,2)
+#endif
+            | MapNode(k2,v2,l,r,h) -> 
+                let c = comparer.Compare(k,k2) 
+                if c < 0 then rebalance (add comparer k v l) k2 v2 r
+                elif c = 0 then MapNode(k,v,l,r,h)
+                else rebalance l k2 v2 (add comparer k v r) 
+
+        let indexNotFound() = raise (new System.Collections.Generic.KeyNotFoundException("An index satisfying the predicate was not found in the collection"))
+
+        let rec find (comparer: IComparer<'T>) k m = 
+            match m with 
+            | MapEmpty -> indexNotFound()
+#if ONE 
+            | MapOne(k2,v2) -> 
+                let c = comparer.Compare(k,k2) 
+                if c = 0 then v2
+                else indexNotFound()
+#endif
+            | MapNode(k2,v2,l,r,_) -> 
+                let c = comparer.Compare(k,k2) 
+                if c < 0 then find comparer k l
+                elif c = 0 then v2
+                else find comparer k r
+
+        let rec tryFind (comparer: IComparer<'T>) k m = 
+            match m with 
+            | MapEmpty -> None
+#if ONE 
+            | MapOne(k2,v2) -> 
+                let c = comparer.Compare(k,k2) 
+                if c = 0 then Some v2
+                else None
+#endif
+            | MapNode(k2,v2,l,r,_) -> 
+                let c = comparer.Compare(k,k2) 
+                if c < 0 then tryFind comparer k l
+                elif c = 0 then Some v2
+                else tryFind comparer k r
+
+        let partition1 (comparer: IComparer<'T>) f k v (acc1,acc2) = 
+            if f k v then (add comparer k v acc1,acc2) else (acc1,add comparer k v acc2) 
+        
+        let rec partitionAux (comparer: IComparer<'T>) f s acc = 
+            match s with 
+            | MapEmpty -> acc
+#if ONE 
+            | MapOne(k,v) -> partition1 comparer f k v acc
+#endif
+            | MapNode(k,v,l,r,_) -> 
+                let acc = partitionAux comparer f r acc 
+                let acc = partition1 comparer f k v acc
+                partitionAux comparer f l acc
+
+        let partition (comparer: IComparer<'T>) f s = partitionAux comparer f s (empty,empty)
+
+        let filter1 (comparer: IComparer<'T>) f k v acc = if f k v then add comparer k v acc else acc 
+
+        let rec filterAux (comparer: IComparer<'T>) f s acc = 
+            match s with 
+            | MapEmpty -> acc
+#if ONE 
+            | MapOne(k,v) -> filter1 comparer f k v acc
+#endif
+            | MapNode(k,v,l,r,_) ->
+                let acc = filterAux comparer f l acc
+                let acc = filter1 comparer f k v acc
+                filterAux comparer f r acc
+
+        let filter (comparer: IComparer<'T>) f s = filterAux comparer f s empty
+
+        let rec spliceOutSuccessor m = 
+            match m with 
+            | MapEmpty -> failwith "internal error: Map.splice_out_succ_or_pred"
+#if ONE 
+            | MapOne(k2,v2) -> k2,v2,MapEmpty
+#endif
+            | MapNode(k2,v2,l,r,_) ->
+                match l with 
+                | MapEmpty -> k2,v2,r
+                | _ -> let k3,v3,l' = spliceOutSuccessor l in k3,v3,mk l' k2 v2 r
+
+        let rec remove (comparer: IComparer<'T>) k m = 
+            match m with 
+            | MapEmpty -> empty
+#if ONE 
+            | MapOne(k2,v2) -> 
+                let c = comparer.Compare(k,k2) 
+                if c = 0 then MapEmpty else m
+#endif
+            | MapNode(k2,v2,l,r,_) -> 
+                let c = comparer.Compare(k,k2) 
+                if c < 0 then rebalance (remove comparer k l) k2 v2 r
+                elif c = 0 then 
+                  match l,r with 
+                  | MapEmpty,_ -> r
+                  | _,MapEmpty -> l
+                  | _ -> 
+                      let sk,sv,r' = spliceOutSuccessor r 
+                      mk l sk sv r'
+                else rebalance l k2 v2 (remove comparer k r) 
+
+        let rec containsKey (comparer: IComparer<'T>) k m = 
+            match m with 
+            | MapEmpty -> false
+#if ONE 
+            | MapOne(k2,v2) -> (comparer.Compare(k,k2) = 0)
+#endif
+            | MapNode(k2,_,l,r,_) -> 
+                let c = comparer.Compare(k,k2) 
+                if c < 0 then containsKey comparer k l
+                else (c = 0 || containsKey comparer k r)
+
+        let rec iter f m = 
+            match m with 
+            | MapEmpty -> ()
+#if ONE 
+            | MapOne(k2,v2) -> f k2 v2
+#endif
+            | MapNode(k2,v2,l,r,_) -> iter f l; f k2 v2; iter f r
+
+        let rec first f m = 
+            match m with 
+            | MapEmpty -> None
+#if ONE 
+            | MapOne(k2,v2) -> f k2 v2 
+#endif
+            | MapNode(k2,v2,l,r,_) -> 
+                match first f l with 
+                | Some _ as res -> res 
+                | None -> 
+                match f k2 v2 with 
+                | Some _ as res -> res 
+                | None -> first f r
+
+        let rec exists f m = 
+            match m with 
+            | MapEmpty -> false
+#if ONE 
+            | MapOne(k2,v2) -> f k2 v2
+#endif
+            | MapNode(k2,v2,l,r,_) -> f k2 v2 || exists f l || exists f r
+
+        let rec forAll f m = 
+            match m with 
+            | MapEmpty -> true
+#if ONE 
+            | MapOne(k2,v2) -> f k2 v2
+#endif
+            | MapNode(k2,v2,l,r,_) -> f k2 v2 && forAll f l && forAll f r
+
+        let rec map f m = 
+            match m with 
+            | MapEmpty -> empty
+#if ONE 
+            | MapOne(k,v) -> MapOne(k,f v)
+#endif
+            | MapNode(k,v,l,r,h) -> let v2 = f v in MapNode(k,v2,map f l, map f r,h)
+
+        let rec mapi f m = 
+            match m with
+            | MapEmpty -> empty
+#if ONE 
+            | MapOne(k,v) -> MapOne(k,f k v)
+#endif
+            | MapNode(k,v,l,r,h) -> let v2 = f k v in MapNode(k,v2, mapi f l, mapi f r,h)
+
+        // Fold, right-to-left. 
+        //
+        // NOTE: This differs from the behaviour of Set.fold which folds left-to-right.
+        let rec fold f m x = 
+            match m with 
+            | MapEmpty -> x
+#if ONE 
+            | MapOne(k,v) -> f k v x
+#endif
+            | MapNode(k,v,l,r,_) -> fold f l (f k v (fold f r x))
+
+        let foldSection (comparer: IComparer<'T>) lo hi f m x =
+            let rec fold_from_to f m x = 
+                match m with 
+                | MapEmpty -> x
+#if ONE 
+                | MapOne(k,v) ->
+                    let clo_k = comparer.Compare(lo,k)
+                    let ck_hi = comparer.Compare(k,hi)
+                    let x = if clo_k <= 0 && ck_hi <= 0 then f k v x else x
+                    x
+#endif
+                | MapNode(k,v,l,r,_) ->
+                    let clo_k = comparer.Compare(lo,k)
+                    let ck_hi = comparer.Compare(k,hi)
+                    let x = if clo_k < 0                then fold_from_to f l x else x
+                    let x = if clo_k <= 0 && ck_hi <= 0 then f k v x                     else x
+                    let x = if ck_hi < 0                then fold_from_to f r x else x
+                    x
+           
+            if comparer.Compare(lo,hi) = 1 then x else fold_from_to f m x
+
+        let rec foldMap (comparer: IComparer<'T>) f m z acc = 
+            match m with 
+            | MapEmpty -> acc,z
+#if ONE 
+            | MapOne(k,v) -> 
+                let v',z = f k v z
+                add comparer k v' acc,z
+#endif
+            | MapNode(k,v,l,r,_) -> 
+                let acc,z = foldMap comparer f r z acc
+                let v',z = f k v z
+                let acc = add comparer k v' acc 
+                foldMap comparer f l z acc
+
+        let toList m = fold (fun k v acc -> (k,v) :: acc) m []
+        let toArray m = m |> toList |> Array.ofList
+        let ofList comparer l = List.fold (fun acc (k,v) -> add comparer k v acc) empty l
+
+        
+        let rec mkFromEnumerator comparer acc (e : IEnumerator<_>) = 
+            if e.MoveNext() then 
+                let (x,y) = e.Current 
+                mkFromEnumerator comparer (add comparer x y acc) e
+            else acc
+          
+        let ofSeq comparer (c : seq<_>) =
+            use ie = c.GetEnumerator()
+            mkFromEnumerator comparer empty ie 
+          
+        let copyToArray s (arr: _[]) i =
+            let j = ref i 
+            s |> iter (fun x y -> arr.[!j] <- KeyValuePair(x,y); j := !j + 1)
+
+
+        /// Imperative left-to-right iterators.
+        type MapIterator<'Key,'T>(s:MapTree<'Key,'T>) = 
+            // collapseLHS:
+            // a) Always returns either [] or a list starting with SetOne.
+            // b) The "fringe" of the set stack is unchanged. 
+            let rec collapseLHS stack =
+                match stack with
+                | []                           -> []
+                | MapEmpty             :: rest -> collapseLHS rest
+#if ONE 
+                | MapOne _         :: _ -> stack
+#else
+                | (MapNode(_,_,MapEmpty,MapEmpty,_)) :: _ -> stack
+#endif
+                | (MapNode(k,v,l,r,_)) :: rest -> collapseLHS (l :: MapOne (k,v) :: r :: rest)
+          
+              /// invariant: always collapseLHS result 
+            let mutable stack = collapseLHS [s]
+               /// true when MoveNext has been called   
+            let mutable started = false
+
+            let notStarted() = raise (new System.InvalidOperationException("Enumeration has not started. Call MoveNext."))
+            let alreadyFinished() = raise (new System.InvalidOperationException("Enumeration already finished."))
+
+            member i.Current =
+                if started then
+                    match stack with
+#if ONE
+                      | MapOne (k,v) :: _ -> new KeyValuePair<_,_>(k,v)
+#else
+                      | (MapNode(k,v,MapEmpty,MapEmpty,_)) :: _ -> new KeyValuePair<_,_>(k,v)
+#endif
+                      | []            -> alreadyFinished()
+                      | _             -> failwith "Please report error: Map iterator, unexpected stack for current"
+                else
+                    notStarted()
+
+            member i.MoveNext() =
+              if started then
+                match stack with
+#if ONE
+                  | MapOne _ :: rest -> 
+#else
+                  | (MapNode(_,_,MapEmpty,MapEmpty,_)) :: rest -> 
+#endif
+                      stack <- collapseLHS rest;
+                      not stack.IsEmpty
+                  | [] -> false
+                  | _ -> failwith "Please report error: Map iterator, unexpected stack for moveNext"
+              else
+                  // The first call to MoveNext "starts" the enumeration. 
+                  started <- true;  
+                  not stack.IsEmpty
+
+        let toSeq s = 
+            let i = ref (MapIterator(s))
+            { new IEnumerator<_> with 
+                  member self.Current = (!i).Current
+              interface System.Collections.IEnumerator with
+                  member self.Current = box (!i).Current
+                  member self.MoveNext() = (!i).MoveNext()
+                  member self.Reset() = i :=  MapIterator(s)
+              interface System.IDisposable with 
+                  member self.Dispose() = ()}
+
+
+#if FX_NO_DEBUG_DISPLAYS
+#else
+    [<System.Diagnostics.DebuggerDisplay ("Count = {Count}")>]
+#endif
+    [<Sealed>]
+    type Map<'Key,'T,'ComparerTag> when 'ComparerTag :> IComparer<'Key>( comparer: IComparer<'Key>, tree: MapTree<'Key,'T>) =
+
+        static let refresh (m:Map<_,_,'ComparerTag>) t =    Map<_,_,'ComparerTag>(comparer=m.ComparerUntyped, tree=t)
+
+        member s.Tree = tree
+        member s.ComparerUntyped : IComparer<'Key> = comparer
+        member s.Comparer = (comparer :?> 'ComparerTag)
+
+        static member Empty(comparer : 'ComparerTag) = Map<'Key,'T,'ComparerTag>(comparer=comparer, tree=MapTree.empty)
+        member m.Add(k,v) = refresh m (MapTree.add comparer k v tree)
+        member m.IsEmpty = MapTree.isEmpty tree
+        member m.Item with get(k : 'Key) = MapTree.find comparer k tree
+        member m.First(f) = MapTree.first f tree 
+        member m.Exists(f) = MapTree.exists f tree 
+        member m.Filter(f) = MapTree.filter comparer f tree |> refresh m 
+        member m.ForAll(f) = MapTree.forAll f tree 
+        member m.Fold f acc = MapTree.fold f tree acc
+        member m.FoldSection lo hi f acc = MapTree.foldSection comparer lo hi f tree acc 
+        member m.FoldAndMap f z  = 
+            let tree,z = MapTree.foldMap comparer f tree z MapTree.empty 
+            refresh m tree, z
+        member m.Iterate f = MapTree.iter f tree
+        member m.MapRange f  = refresh m (MapTree.map f tree)
+        member m.Map f  = refresh m (MapTree.mapi f tree)
+        member m.Partition(f)  =
+            let r1,r2 = MapTree.partition comparer f tree  
+            refresh m r1, refresh m r2
+        member m.Count = MapTree.count tree
+        member m.ContainsKey(k) = MapTree.containsKey comparer k tree
+        member m.Remove(k)  = refresh m (MapTree.remove comparer k tree)
+        member m.TryFind(k) = MapTree.tryFind comparer k tree
+        member m.ToList() = MapTree.toList tree
+        member m.ToArray() = MapTree.toArray tree
+
+        static member FromList(comparer : 'ComparerTag,l) : Map<'Key,'T,'ComparerTag> = 
+            Map<_,_,_>(comparer=comparer, tree=MapTree.ofList comparer l)
+
+        static member Create(comparer : 'ComparerTag, ie : seq<_>) : Map<'Key,'T,'ComparerTag> = 
+            Map<_,_,_>(comparer=comparer, tree=MapTree.ofSeq comparer ie)
+    
+        interface IEnumerable<KeyValuePair<'Key, 'T>> with
+            member s.GetEnumerator() = MapTree.toSeq tree
+
+        interface System.Collections.IEnumerable with
+            override s.GetEnumerator() = (MapTree.toSeq tree :> System.Collections.IEnumerator)
+
+        override this.Equals(that) = 
+            match that with
+            // Cast to the exact same type as this, otherwise not equal.
+            | :? Map<'Key,'T,'ComparerTag> as that -> ((this :> System.IComparable).CompareTo(that) = 0)
+            | _ -> false
+
+        interface System.IComparable with 
+             member m1.CompareTo(m2: obj) = 
+                 Seq.compareWith 
+                   (fun (kvp1 : KeyValuePair<_,_>) (kvp2 : KeyValuePair<_,_>)-> 
+                       let c = m1.ComparerUntyped.Compare(kvp1.Key,kvp2.Key) in 
+                       if c <> 0 then c else Unchecked.compare kvp1.Value kvp2.Value)
+                   // Cast m2 to the exact same type as m1, see 4884.
+                   // It is not OK to cast m2 to seq<KeyValuePair<'Key,'T>>, since different compares could permute the KVPs.
+                   m1 (m2 :?> Map<'Key,'T,'ComparerTag>)
+
+        member this.ComputeHashCode() = 
+            let combineHash x y = (x <<< 1) + y + 631 
+            let mutable res = 0
+            for KeyValue(x,y) in this do
+                res <- combineHash res (Unchecked.hash x)
+                res <- combineHash res (Unchecked.hash y)
+            abs res
+
+        override this.GetHashCode() = this.ComputeHashCode()
+
+
+    type Map<'Key,'T> = Map<'Key, 'T, IComparer<'Key>>    
+    type Set<'T> = Set<'T, IComparer<'T>>    
+
--- fsharp-3.1.1.26+dfsg2.orig/FSharp.PowerPack/TaggedCollections.fsi
+++ fsharp-3.1.1.26+dfsg2/FSharp.PowerPack/TaggedCollections.fsi
@@ -1,225 +1,225 @@
-// (c) Microsoft Corporation 2005-2009. 
-
-/// This namespace contains FSharp.PowerPack extensions for the F# collection types
-namespace Microsoft.FSharp.Collections.Tagged
-
-    open System
-    open System.Collections.Generic
-
-
-    /// Immutable sets based on binary trees, default tag
-
-    /// Immutable sets where a constraint tag carries information about the class of key-comparer being used.  
-    [<Sealed>]
-    type Set<'T,'ComparerTag> when 'ComparerTag :> IComparer<'T> =
-
-        /// Gets the comparer used for the set.
-        member Comparer : 'ComparerTag
-
-        /// A useful shortcut for Set.add.  Note this operation prodcues a new set
-        /// and does not mutate the original set.  The new set will share many storage
-        /// nodes with the original.  See the Set module for further operations on sets.
-        member Add : 'T -> Set<'T,'ComparerTag>
-        
-        /// A useful shortcut for Set.remove.  Note this operation produces a new set
-        /// and does not mutate the original set.  The new set will share many storage
-        /// nodes with the original.  See the Set module for further operations on sets.
-        member Remove : 'T -> Set<'T,'ComparerTag>
-        
-        /// Return the number of elements in the set
-        member Count : int
-        
-        /// A useful shortcut for Set.contains.  See the Set module for further operations on sets.
-        member Contains : 'T -> bool
-        
-        /// A useful shortcut for Set.isEmpty.  See the Set module for further operations on sets.
-        member IsEmpty  : bool
-
-        /// Apply the given function to each binding in the collection
-        member Iterate : ('T -> unit) -> unit
-
-        /// Apply the given accumulating function to all the elements of the set
-        member Fold    : ('T -> 'State -> 'State) -> 'State -> 'State
-
-        /// Build two new sets, one containing the elements for which the given predicate returns 'true',
-        /// and the other the remaining elements.
-        member Partition: predicate:('T -> bool) -> Set<'T,'ComparerTag> * Set<'T,'ComparerTag>
-
-        /// Return a new collection containing only the elements of the collection
-        /// for which the given predicate returns "true"
-        member Filter: predicate:('T -> bool) -> Set<'T,'ComparerTag> 
-
-        /// Test if any element of the collection satisfies the given predicate.
-        /// If the input function is <c>f</c> and the elements are <c>i0...iN</c> then computes 
-        /// <c>p i0 or ... or p iN</c>.
-        member Exists: predicate:('T -> bool) -> bool
-
-        /// Test if all elements of the collection satisfy the given predicate.
-        /// If the input function is <c>f</c> and the elements are <c>i0...iN</c> and <c>j0...jN</c> then 
-        /// computes <c>p i0 && ... && p iN</c>.
-        member ForAll: predicate:('T -> bool) -> bool
-
-        /// A set based on the given comparer containing the given initial elements
-        static member Create: 'ComparerTag * seq<'T> -> Set<'T,'ComparerTag> 
-        
-        /// The empty set based on the given comparer
-        static member Empty: 'ComparerTag -> Set<'T,'ComparerTag> 
-        
-        /// A singleton set based on the given comparison operator
-        static member Singleton: 'ComparerTag * 'T -> Set<'T,'ComparerTag> 
-        
-        /// Compares two sets and returns true if they are equal or false otherwise
-        static member Equality : Set<'T,'ComparerTag> * Set<'T,'ComparerTag> -> bool
-        
-        /// Compares a and b and returns 1 if a > b, -1 if b < a and 0 if a = b        
-        static member Compare : a:Set<'T,'ComparerTag> * b:Set<'T,'ComparerTag> -> int
-
-        /// Return a new set with the elements of the second set removed from the first.
-        static member (-) : Set<'T,'ComparerTag> * Set<'T,'ComparerTag> -> Set<'T,'ComparerTag> 
-
-        /// Compute the union of the two sets.
-        static member (+) : Set<'T,'ComparerTag> * Set<'T,'ComparerTag> -> Set<'T,'ComparerTag> 
-
-        /// Compute the intersection of the two sets.
-        static member Intersection : Set<'T,'ComparerTag> * Set<'T,'ComparerTag> -> Set<'T,'ComparerTag> 
-
-        /// Compute the union of the two sets.
-        static member Union : Set<'T,'ComparerTag> * Set<'T,'ComparerTag> -> Set<'T,'ComparerTag>
-
-        /// Return a new set with the elements of the second set removed from the first.
-        static member Difference: Set<'T,'ComparerTag> * Set<'T,'ComparerTag> -> Set<'T,'ComparerTag> 
-
-        /// The number of elements in the set
-        member Choose : 'T 
-
-        /// Returns the lowest element in the set according to the ordering being used for the set
-        member MinimumElement: 'T
-
-        /// Returns the highest element in the set according to the ordering being used for the set
-        member MaximumElement: 'T
-
-        /// Evaluates to "true" if all elements of the second set are in the first
-        member IsSubsetOf: Set<'T,'ComparerTag> -> bool
-
-        /// Evaluates to "true" if all elements of the first set are in the second
-        member IsSupersetOf: Set<'T,'ComparerTag> -> bool
-
-        /// The elements of the set as a list.
-        member ToList : unit -> 'T list
-        
-        /// The elements of the set as an array.
-        member ToArray: unit -> 'T array 
-
-        interface ICollection<'T> 
-        interface IEnumerable<'T> 
-        interface System.Collections.IEnumerable
-
-        interface System.IComparable
-        override Equals : obj -> bool
-
-    type Set<'T> = Set<'T, IComparer<'T>>    
-
-    /// Immutable maps.  Keys are ordered by construction function specified
-    /// when creating empty maps or by F# structural comparison if no
-    /// construction function is specified.
-    ///
-    /// <performance> 
-    ///   Maps based on structural comparison are  
-    ///   efficient for small keys. They are not a suitable choice if keys are recursive data structures 
-    ///   or require non-structural comparison semantics.
-    /// </performance>
-
-    /// Immutable maps.  A constraint tag carries information about the class of key-comparers being used.  
-    [<Sealed>]
-    type Map<'Key,'Value,'ComparerTag>  when 'ComparerTag :> IComparer<'Key> =
-        /// Return a new map with the binding added to the given map.
-        member Add: 'Key * 'Value -> Map<'Key,'Value,'ComparerTag>
-
-        /// Gets a value indicating whether there are no bindings in the map.
-        member IsEmpty: bool
-        
-        /// Gets the comparer used for the map.
-        member Comparer : 'ComparerTag
-
-        /// The empty map, and use the given comparer comparison function for all operations associated
-        /// with any maps built from this map.
-        static member Empty: 'ComparerTag -> Map<'Key,'Value,'ComparerTag>
-
-        static member FromList : 'ComparerTag * ('Key * 'Value) list -> Map<'Key,'Value,'ComparerTag>
-
-        /// Build a map that contains the bindings of the given IEnumerable
-        /// and where comparison of elements is based on the given comparison function
-        static member Create: 'ComparerTag * seq<'Key * 'Value> -> Map<'Key,'Value,'ComparerTag> 
-
-        /// Test is an element is in the domain of the map
-        member ContainsKey: 'Key -> bool
-
-        /// The number of bindings in the map
-        member Count: int
-
-        /// Lookup an element in the map. Raise <c>KeyNotFoundException</c> if no binding
-        /// exists in the map.
-        member Item : 'Key -> 'Value with get
-
-        /// Search the map looking for the first element where the given function returns a <c>Some</c> value
-        member First: ('Key -> 'Value -> 'T option) -> 'T option
-
-        /// Return true if the given predicate returns true for all of the
-        /// bindings in the map. Always returns true if the map is empty.
-        member ForAll: ('Key -> 'Value -> bool) -> bool
-
-        /// Return true if the given predicate returns true for one of the
-        /// bindings in the map. Always returns false if the map is empty.
-        member Exists: ('Key -> 'Value -> bool) -> bool
-
-        /// Build a new map containing the bindings for which the given predicate returns 'true'.
-        member Filter: ('Key -> 'Value -> bool) -> Map<'Key,'Value,'ComparerTag> 
-
-        /// Fold over the bindings in the map.  
-        member Fold: folder:('Key -> 'Value -> 'State -> 'State) -> 'State -> 'State
-
-        /// Given the start and end points of a key range,
-        /// Fold over the bindings in the map that are in the range,
-        /// and the end points are included if present (the range is considered a closed interval).
-        member FoldSection: 'Key -> 'Key -> ('Key -> 'Value -> 'State -> 'State) -> 'State -> 'State
-
-        /// Fold over the bindings in the map.  
-        member FoldAndMap: ('Key -> 'Value -> 'State -> 'T * 'State) -> 'State -> Map<'Key,'T,'ComparerTag> * 'State
-
-        /// Apply the given function to each binding in the dictionary
-        member Iterate: action:('Key -> 'Value -> unit) -> unit
-
-        /// Build a new collection whose elements are the results of applying the given function
-        /// to each of the elements of the collection. The index passed to the
-        /// function indicates the index of element being transformed.
-        member Map: mapping:('Key -> 'Value -> 'T) -> Map<'Key,'T,'ComparerTag>
-
-        /// Build a new collection whose elements are the results of applying the given function
-        /// to each of the elements of the collection.
-        member MapRange: mapping:('Value -> 'T) -> Map<'Key,'T,'ComparerTag>
-
-        /// Build two new maps, one containing the bindings for which the given predicate returns 'true',
-        /// and the other the remaining bindings.
-        member Partition: ('Key -> 'Value -> bool) -> Map<'Key,'Value,'ComparerTag> * Map<'Key,'Value,'ComparerTag>
-
-        /// Remove an element from the domain of the map.  No exception is raised if the element is not present.
-        member Remove: 'Key -> Map<'Key,'Value,'ComparerTag>
-
-        /// Lookup an element in the map, returning a <c>Some</c> value if the element is in the domain 
-        /// of the map and <c>None</c> if not.
-        member TryFind: 'Key -> 'Value option
-
-        /// The elements of the set as a list.
-        member ToList : unit -> ('Key * 'Value) list
-    
-        /// The elements of the set as an array
-        member ToArray: unit -> ('Key * 'Value) array 
-
-        interface IEnumerable<KeyValuePair<'Key, 'Value>>
-        
-        interface System.Collections.IEnumerable 
-        interface System.IComparable
-        override Equals : obj -> bool
-
-    type Map<'Key,'Value> = Map<'Key, 'Value, IComparer<'Key>>    
-
+// (c) Microsoft Corporation 2005-2009. 
+
+/// This namespace contains FSharp.PowerPack extensions for the F# collection types
+namespace Microsoft.FSharp.Collections.Tagged
+
+    open System
+    open System.Collections.Generic
+
+
+    /// Immutable sets based on binary trees, default tag
+
+    /// Immutable sets where a constraint tag carries information about the class of key-comparer being used.  
+    [<Sealed>]
+    type Set<'T,'ComparerTag> when 'ComparerTag :> IComparer<'T> =
+
+        /// Gets the comparer used for the set.
+        member Comparer : 'ComparerTag
+
+        /// A useful shortcut for Set.add.  Note this operation prodcues a new set
+        /// and does not mutate the original set.  The new set will share many storage
+        /// nodes with the original.  See the Set module for further operations on sets.
+        member Add : 'T -> Set<'T,'ComparerTag>
+        
+        /// A useful shortcut for Set.remove.  Note this operation produces a new set
+        /// and does not mutate the original set.  The new set will share many storage
+        /// nodes with the original.  See the Set module for further operations on sets.
+        member Remove : 'T -> Set<'T,'ComparerTag>
+        
+        /// Return the number of elements in the set
+        member Count : int
+        
+        /// A useful shortcut for Set.contains.  See the Set module for further operations on sets.
+        member Contains : 'T -> bool
+        
+        /// A useful shortcut for Set.isEmpty.  See the Set module for further operations on sets.
+        member IsEmpty  : bool
+
+        /// Apply the given function to each binding in the collection
+        member Iterate : ('T -> unit) -> unit
+
+        /// Apply the given accumulating function to all the elements of the set
+        member Fold    : ('T -> 'State -> 'State) -> 'State -> 'State
+
+        /// Build two new sets, one containing the elements for which the given predicate returns 'true',
+        /// and the other the remaining elements.
+        member Partition: predicate:('T -> bool) -> Set<'T,'ComparerTag> * Set<'T,'ComparerTag>
+
+        /// Return a new collection containing only the elements of the collection
+        /// for which the given predicate returns "true"
+        member Filter: predicate:('T -> bool) -> Set<'T,'ComparerTag> 
+
+        /// Test if any element of the collection satisfies the given predicate.
+        /// If the input function is <c>f</c> and the elements are <c>i0...iN</c> then computes 
+        /// <c>p i0 or ... or p iN</c>.
+        member Exists: predicate:('T -> bool) -> bool
+
+        /// Test if all elements of the collection satisfy the given predicate.
+        /// If the input function is <c>f</c> and the elements are <c>i0...iN</c> and <c>j0...jN</c> then 
+        /// computes <c>p i0 && ... && p iN</c>.
+        member ForAll: predicate:('T -> bool) -> bool
+
+        /// A set based on the given comparer containing the given initial elements
+        static member Create: 'ComparerTag * seq<'T> -> Set<'T,'ComparerTag> 
+        
+        /// The empty set based on the given comparer
+        static member Empty: 'ComparerTag -> Set<'T,'ComparerTag> 
+        
+        /// A singleton set based on the given comparison operator
+        static member Singleton: 'ComparerTag * 'T -> Set<'T,'ComparerTag> 
+        
+        /// Compares two sets and returns true if they are equal or false otherwise
+        static member Equality : Set<'T,'ComparerTag> * Set<'T,'ComparerTag> -> bool
+        
+        /// Compares a and b and returns 1 if a > b, -1 if b < a and 0 if a = b        
+        static member Compare : a:Set<'T,'ComparerTag> * b:Set<'T,'ComparerTag> -> int
+
+        /// Return a new set with the elements of the second set removed from the first.
+        static member (-) : Set<'T,'ComparerTag> * Set<'T,'ComparerTag> -> Set<'T,'ComparerTag> 
+
+        /// Compute the union of the two sets.
+        static member (+) : Set<'T,'ComparerTag> * Set<'T,'ComparerTag> -> Set<'T,'ComparerTag> 
+
+        /// Compute the intersection of the two sets.
+        static member Intersection : Set<'T,'ComparerTag> * Set<'T,'ComparerTag> -> Set<'T,'ComparerTag> 
+
+        /// Compute the union of the two sets.
+        static member Union : Set<'T,'ComparerTag> * Set<'T,'ComparerTag> -> Set<'T,'ComparerTag>
+
+        /// Return a new set with the elements of the second set removed from the first.
+        static member Difference: Set<'T,'ComparerTag> * Set<'T,'ComparerTag> -> Set<'T,'ComparerTag> 
+
+        /// The number of elements in the set
+        member Choose : 'T 
+
+        /// Returns the lowest element in the set according to the ordering being used for the set
+        member MinimumElement: 'T
+
+        /// Returns the highest element in the set according to the ordering being used for the set
+        member MaximumElement: 'T
+
+        /// Evaluates to "true" if all elements of the second set are in the first
+        member IsSubsetOf: Set<'T,'ComparerTag> -> bool
+
+        /// Evaluates to "true" if all elements of the first set are in the second
+        member IsSupersetOf: Set<'T,'ComparerTag> -> bool
+
+        /// The elements of the set as a list.
+        member ToList : unit -> 'T list
+        
+        /// The elements of the set as an array.
+        member ToArray: unit -> 'T array 
+
+        interface ICollection<'T> 
+        interface IEnumerable<'T> 
+        interface System.Collections.IEnumerable
+
+        interface System.IComparable
+        override Equals : obj -> bool
+
+    type Set<'T> = Set<'T, IComparer<'T>>    
+
+    /// Immutable maps.  Keys are ordered by construction function specified
+    /// when creating empty maps or by F# structural comparison if no
+    /// construction function is specified.
+    ///
+    /// <performance> 
+    ///   Maps based on structural comparison are  
+    ///   efficient for small keys. They are not a suitable choice if keys are recursive data structures 
+    ///   or require non-structural comparison semantics.
+    /// </performance>
+
+    /// Immutable maps.  A constraint tag carries information about the class of key-comparers being used.  
+    [<Sealed>]
+    type Map<'Key,'Value,'ComparerTag>  when 'ComparerTag :> IComparer<'Key> =
+        /// Return a new map with the binding added to the given map.
+        member Add: 'Key * 'Value -> Map<'Key,'Value,'ComparerTag>
+
+        /// Gets a value indicating whether there are no bindings in the map.
+        member IsEmpty: bool
+        
+        /// Gets the comparer used for the map.
+        member Comparer : 'ComparerTag
+
+        /// The empty map, and use the given comparer comparison function for all operations associated
+        /// with any maps built from this map.
+        static member Empty: 'ComparerTag -> Map<'Key,'Value,'ComparerTag>
+
+        static member FromList : 'ComparerTag * ('Key * 'Value) list -> Map<'Key,'Value,'ComparerTag>
+
+        /// Build a map that contains the bindings of the given IEnumerable
+        /// and where comparison of elements is based on the given comparison function
+        static member Create: 'ComparerTag * seq<'Key * 'Value> -> Map<'Key,'Value,'ComparerTag> 
+
+        /// Test is an element is in the domain of the map
+        member ContainsKey: 'Key -> bool
+
+        /// The number of bindings in the map
+        member Count: int
+
+        /// Lookup an element in the map. Raise <c>KeyNotFoundException</c> if no binding
+        /// exists in the map.
+        member Item : 'Key -> 'Value with get
+
+        /// Search the map looking for the first element where the given function returns a <c>Some</c> value
+        member First: ('Key -> 'Value -> 'T option) -> 'T option
+
+        /// Return true if the given predicate returns true for all of the
+        /// bindings in the map. Always returns true if the map is empty.
+        member ForAll: ('Key -> 'Value -> bool) -> bool
+
+        /// Return true if the given predicate returns true for one of the
+        /// bindings in the map. Always returns false if the map is empty.
+        member Exists: ('Key -> 'Value -> bool) -> bool
+
+        /// Build a new map containing the bindings for which the given predicate returns 'true'.
+        member Filter: ('Key -> 'Value -> bool) -> Map<'Key,'Value,'ComparerTag> 
+
+        /// Fold over the bindings in the map.  
+        member Fold: folder:('Key -> 'Value -> 'State -> 'State) -> 'State -> 'State
+
+        /// Given the start and end points of a key range,
+        /// Fold over the bindings in the map that are in the range,
+        /// and the end points are included if present (the range is considered a closed interval).
+        member FoldSection: 'Key -> 'Key -> ('Key -> 'Value -> 'State -> 'State) -> 'State -> 'State
+
+        /// Fold over the bindings in the map.  
+        member FoldAndMap: ('Key -> 'Value -> 'State -> 'T * 'State) -> 'State -> Map<'Key,'T,'ComparerTag> * 'State
+
+        /// Apply the given function to each binding in the dictionary
+        member Iterate: action:('Key -> 'Value -> unit) -> unit
+
+        /// Build a new collection whose elements are the results of applying the given function
+        /// to each of the elements of the collection. The index passed to the
+        /// function indicates the index of element being transformed.
+        member Map: mapping:('Key -> 'Value -> 'T) -> Map<'Key,'T,'ComparerTag>
+
+        /// Build a new collection whose elements are the results of applying the given function
+        /// to each of the elements of the collection.
+        member MapRange: mapping:('Value -> 'T) -> Map<'Key,'T,'ComparerTag>
+
+        /// Build two new maps, one containing the bindings for which the given predicate returns 'true',
+        /// and the other the remaining bindings.
+        member Partition: ('Key -> 'Value -> bool) -> Map<'Key,'Value,'ComparerTag> * Map<'Key,'Value,'ComparerTag>
+
+        /// Remove an element from the domain of the map.  No exception is raised if the element is not present.
+        member Remove: 'Key -> Map<'Key,'Value,'ComparerTag>
+
+        /// Lookup an element in the map, returning a <c>Some</c> value if the element is in the domain 
+        /// of the map and <c>None</c> if not.
+        member TryFind: 'Key -> 'Value option
+
+        /// The elements of the set as a list.
+        member ToList : unit -> ('Key * 'Value) list
+    
+        /// The elements of the set as an array
+        member ToArray: unit -> ('Key * 'Value) array 
+
+        interface IEnumerable<KeyValuePair<'Key, 'Value>>
+        
+        interface System.Collections.IEnumerable 
+        interface System.IComparable
+        override Equals : obj -> bool
+
+    type Map<'Key,'Value> = Map<'Key, 'Value, IComparer<'Key>>    
+
--- fsharp-3.1.1.26+dfsg2.orig/FSharp.PowerPack/TaggedHash.fs
+++ fsharp-3.1.1.26+dfsg2/FSharp.PowerPack/TaggedHash.fs
@@ -1,59 +1,59 @@
-// (c) Microsoft Corporation 2005-2009. 
-
-namespace Microsoft.FSharp.Collections.Tagged
-
-    #nowarn "51"
-
-    open System
-    open System.Collections.Generic
-    open Microsoft.FSharp.Collections
-    type UntaggedHashMultiMap<'Key,'Value> = Microsoft.FSharp.Collections.HashMultiMap<'Key,'Value>
-
-    type HashMultiMap<'Key,'Value,'HashTag>
-         when 'HashTag :> IEqualityComparer<'Key> =
-        { t : UntaggedHashMultiMap<'Key,'Value> }
-
-        static member Create(hasheq: 'HashTag,n:int)  : HashMultiMap<'Key,'Value,'HashTag> = 
-            { t = new UntaggedHashMultiMap<_,_>(n,hasheq) }
-
-        member x.Add(y,z) = x.t.Add(y,z)
-        member x.Clear() = x.t.Clear()
-        member x.Copy() : HashMultiMap<'Key,'Value,'HashTag>  = { t = x.t.Copy() }
-        member x.Item with get(y) = x.t.[y]
-                      and  set y z = x.t.[y] <- z
-        member x.FindAll(y) = x.t.FindAll(y) 
-        member x.Fold f acc =  x.t.Fold f acc
-        member x.Iterate(f) =  x.t.Iterate(f)
-        member x.Contains(y) = x.t.ContainsKey(y)
-        member x.ContainsKey(y) = x.t.ContainsKey(y)
-        member x.Remove(y) = x.t.Remove(y)
-        member x.Replace(y,z) = x.t.Replace(y,z)
-        member x.TryFind(y) = x.t.TryFind(y)
-        member x.Count = x.t.Count
-
-    type HashMultiMap<'Key,'Value> = HashMultiMap<'Key,'Value, IEqualityComparer<'Key>>    
-
-
-    [<Sealed>]
-    type HashSet<'T,'HashTag when 'T : equality> 
-         when 'HashTag :> IEqualityComparer<'T>(t:  HashSet<'T>) =
-
-        static member Create(hasheq: ('HashTag :> IEqualityComparer<'T>),size:int) : HashSet<'T,'HashTag> = 
-            new HashSet<'T,'HashTag>(HashSet<_>(size,hasheq))
-
-        member x.Add(y)    = t.Add(y)
-        member x.Clear() = t.Clear()
-        member x.Copy() = new HashSet<'T,'HashTag>(t.Copy())
-        member x.Fold f acc = t.Fold f acc
-        member x.Iterate(f) =  t.Iterate(f)
-        member x.Contains(y) = t.Contains(y)
-        member x.Remove(y) = t.Remove(y)
-        member x.Count = t.Count
-
-        interface IEnumerable<'T> with
-            member x.GetEnumerator() = (t :> seq<_>).GetEnumerator() 
-
-        interface System.Collections.IEnumerable with 
-            member x.GetEnumerator() = (t :> System.Collections.IEnumerable).GetEnumerator()  
-
-    type HashSet<'T when 'T : equality> = HashSet<'T, IEqualityComparer<'T>>    
+// (c) Microsoft Corporation 2005-2009. 
+
+namespace Microsoft.FSharp.Collections.Tagged
+
+    #nowarn "51"
+
+    open System
+    open System.Collections.Generic
+    open Microsoft.FSharp.Collections
+    type UntaggedHashMultiMap<'Key,'Value> = Microsoft.FSharp.Collections.HashMultiMap<'Key,'Value>
+
+    type HashMultiMap<'Key,'Value,'HashTag>
+         when 'HashTag :> IEqualityComparer<'Key> =
+        { t : UntaggedHashMultiMap<'Key,'Value> }
+
+        static member Create(hasheq: 'HashTag,n:int)  : HashMultiMap<'Key,'Value,'HashTag> = 
+            { t = new UntaggedHashMultiMap<_,_>(n,hasheq) }
+
+        member x.Add(y,z) = x.t.Add(y,z)
+        member x.Clear() = x.t.Clear()
+        member x.Copy() : HashMultiMap<'Key,'Value,'HashTag>  = { t = x.t.Copy() }
+        member x.Item with get(y) = x.t.[y]
+                      and  set y z = x.t.[y] <- z
+        member x.FindAll(y) = x.t.FindAll(y) 
+        member x.Fold f acc =  x.t.Fold f acc
+        member x.Iterate(f) =  x.t.Iterate(f)
+        member x.Contains(y) = x.t.ContainsKey(y)
+        member x.ContainsKey(y) = x.t.ContainsKey(y)
+        member x.Remove(y) = x.t.Remove(y)
+        member x.Replace(y,z) = x.t.Replace(y,z)
+        member x.TryFind(y) = x.t.TryFind(y)
+        member x.Count = x.t.Count
+
+    type HashMultiMap<'Key,'Value> = HashMultiMap<'Key,'Value, IEqualityComparer<'Key>>    
+
+
+    [<Sealed>]
+    type HashSet<'T,'HashTag when 'T : equality> 
+         when 'HashTag :> IEqualityComparer<'T>(t:  HashSet<'T>) =
+
+        static member Create(hasheq: ('HashTag :> IEqualityComparer<'T>),size:int) : HashSet<'T,'HashTag> = 
+            new HashSet<'T,'HashTag>(HashSet<_>(size,hasheq))
+
+        member x.Add(y)    = t.Add(y)
+        member x.Clear() = t.Clear()
+        member x.Copy() = new HashSet<'T,'HashTag>(t.Copy())
+        member x.Fold f acc = t.Fold f acc
+        member x.Iterate(f) =  t.Iterate(f)
+        member x.Contains(y) = t.Contains(y)
+        member x.Remove(y) = t.Remove(y)
+        member x.Count = t.Count
+
+        interface IEnumerable<'T> with
+            member x.GetEnumerator() = (t :> seq<_>).GetEnumerator() 
+
+        interface System.Collections.IEnumerable with 
+            member x.GetEnumerator() = (t :> System.Collections.IEnumerable).GetEnumerator()  
+
+    type HashSet<'T when 'T : equality> = HashSet<'T, IEqualityComparer<'T>>    
--- fsharp-3.1.1.26+dfsg2.orig/FSharp.PowerPack/TaggedHash.fsi
+++ fsharp-3.1.1.26+dfsg2/FSharp.PowerPack/TaggedHash.fsi
@@ -1,89 +1,89 @@
-// (c) Microsoft Corporation 2005-2009. 
-
-namespace Microsoft.FSharp.Collections.Tagged
-
-    open System
-    open System.Collections.Generic
-
-    /// HashMultiMap, but where a constraint tag tracks information about the hash/equality functions used
-    /// for the hashing. When the tag is Tags.StructuralHash this is identical to HashMultiMap.
-    [<Sealed>]
-    type HashMultiMap<'Key,'Value,'HashTag> when 'HashTag :> IEqualityComparer<'Key> =
-        /// Create a new empty mutable hash table with an internal bucket array of the given approximate size
-        /// and with the given key hash/equality functions
-        static member Create: 'HashTag * int             -> HashMultiMap<'Key,'Value,'HashTag>
-
-        /// Make a shallow copy of the collection
-        member Copy    : unit    -> HashMultiMap<'Key,'Value,'HashTag>
-
-        /// Add a binding for the element to the table
-        member Add     : 'Key * 'Value -> unit
-
-        /// Clear all elements from the collection
-        member Clear   : unit    -> unit
-
-        /// Test if the collection contains any bindings for the given element
-        [<System.Obsolete("This member has been renamed to ContainsKey")>]
-        member Contains: 'Key      -> bool
-
-        /// Test if the collection contains any bindings for the given element
-        member ContainsKey: 'Key      -> bool
-
-        /// Remove the latest binding (if any) for the given element from the table
-        member Remove  : 'Key      -> unit
-
-        /// Replace the latest binding (if any) for the given element.
-        member Replace : 'Key * 'Value -> unit
-
-        /// Lookup or set the given element in the table.  Raise <c>KeyNotFoundException</c> if the element is not found.
-        member Item : 'Key -> 'Value with get,set
-
-        /// Lookup the given element in the table, returning the result as an Option
-        member TryFind : 'Key      -> 'Value option
-        /// Find all bindings for the given element in the table, if any
-        member FindAll : 'Key      -> 'Value list
-
-        /// Apply the given function to each element in the collection threading the accumulating parameter
-        /// through the sequence of function applications
-        member Fold    : ('Key -> 'Value -> 'c -> 'c) -> 'c -> 'c
-
-        /// The number of bindings in the hash table
-        member Count   : int
-
-        /// Apply the given function to each binding in the hash table 
-        member Iterate : ('Key -> 'Value -> unit) -> unit
-
-    type HashMultiMap<'Key,'Value> = HashMultiMap<'Key,'Value, IEqualityComparer<'Key>>    
-
-    /// Mutable hash sets where a constraint tag tracks information about the hash/equality functions used
-    /// for the hashing. When the tag is Tags.StructuralHash this is identical to HashSet.
-    [<Sealed>]
-    type HashSet<'T,'HashTag> when 'T : equality and 'HashTag :> IEqualityComparer<'T>  =
-        /// Create a new empty mutable hash set with an internal bucket array of the given approximate size
-        /// and with the given key hash/equality functions 
-        static member Create: 'HashTag * int             -> HashSet<'T,'HashTag>
-
-        /// Make a shallow copy of the set
-        member Copy    : unit -> HashSet<'T,'HashTag>
-        /// Add an element to the collection
-        member Add     : 'T   -> unit
-        /// Clear all elements from the set
-        member Clear   : unit -> unit
-        /// Test if the set contains the given element
-        member Contains: 'T   -> bool
-        /// Remove the given element from the set
-        member Remove  : 'T   -> unit
-        /// Apply the given function to the set threading the accumulating parameter
-        /// through the sequence of function applications
-        member Fold    : ('T -> 'State -> 'State) -> 'State -> 'State
-        
-        /// The number of elements in the set
-        member Count   : int
-
-        /// Apply the given function to each binding in the hash table 
-        member Iterate : ('T -> unit) -> unit
-
-        interface IEnumerable<'T> 
-        interface System.Collections.IEnumerable 
-
-    type HashSet<'T when 'T : equality> = HashSet<'T, IEqualityComparer<'T>>    
+// (c) Microsoft Corporation 2005-2009. 
+
+namespace Microsoft.FSharp.Collections.Tagged
+
+    open System
+    open System.Collections.Generic
+
+    /// HashMultiMap, but where a constraint tag tracks information about the hash/equality functions used
+    /// for the hashing. When the tag is Tags.StructuralHash this is identical to HashMultiMap.
+    [<Sealed>]
+    type HashMultiMap<'Key,'Value,'HashTag> when 'HashTag :> IEqualityComparer<'Key> =
+        /// Create a new empty mutable hash table with an internal bucket array of the given approximate size
+        /// and with the given key hash/equality functions
+        static member Create: 'HashTag * int             -> HashMultiMap<'Key,'Value,'HashTag>
+
+        /// Make a shallow copy of the collection
+        member Copy    : unit    -> HashMultiMap<'Key,'Value,'HashTag>
+
+        /// Add a binding for the element to the table
+        member Add     : 'Key * 'Value -> unit
+
+        /// Clear all elements from the collection
+        member Clear   : unit    -> unit
+
+        /// Test if the collection contains any bindings for the given element
+        [<System.Obsolete("This member has been renamed to ContainsKey")>]
+        member Contains: 'Key      -> bool
+
+        /// Test if the collection contains any bindings for the given element
+        member ContainsKey: 'Key      -> bool
+
+        /// Remove the latest binding (if any) for the given element from the table
+        member Remove  : 'Key      -> unit
+
+        /// Replace the latest binding (if any) for the given element.
+        member Replace : 'Key * 'Value -> unit
+
+        /// Lookup or set the given element in the table.  Raise <c>KeyNotFoundException</c> if the element is not found.
+        member Item : 'Key -> 'Value with get,set
+
+        /// Lookup the given element in the table, returning the result as an Option
+        member TryFind : 'Key      -> 'Value option
+        /// Find all bindings for the given element in the table, if any
+        member FindAll : 'Key      -> 'Value list
+
+        /// Apply the given function to each element in the collection threading the accumulating parameter
+        /// through the sequence of function applications
+        member Fold    : ('Key -> 'Value -> 'c -> 'c) -> 'c -> 'c
+
+        /// The number of bindings in the hash table
+        member Count   : int
+
+        /// Apply the given function to each binding in the hash table 
+        member Iterate : ('Key -> 'Value -> unit) -> unit
+
+    type HashMultiMap<'Key,'Value> = HashMultiMap<'Key,'Value, IEqualityComparer<'Key>>    
+
+    /// Mutable hash sets where a constraint tag tracks information about the hash/equality functions used
+    /// for the hashing. When the tag is Tags.StructuralHash this is identical to HashSet.
+    [<Sealed>]
+    type HashSet<'T,'HashTag> when 'T : equality and 'HashTag :> IEqualityComparer<'T>  =
+        /// Create a new empty mutable hash set with an internal bucket array of the given approximate size
+        /// and with the given key hash/equality functions 
+        static member Create: 'HashTag * int             -> HashSet<'T,'HashTag>
+
+        /// Make a shallow copy of the set
+        member Copy    : unit -> HashSet<'T,'HashTag>
+        /// Add an element to the collection
+        member Add     : 'T   -> unit
+        /// Clear all elements from the set
+        member Clear   : unit -> unit
+        /// Test if the set contains the given element
+        member Contains: 'T   -> bool
+        /// Remove the given element from the set
+        member Remove  : 'T   -> unit
+        /// Apply the given function to the set threading the accumulating parameter
+        /// through the sequence of function applications
+        member Fold    : ('T -> 'State -> 'State) -> 'State -> 'State
+        
+        /// The number of elements in the set
+        member Count   : int
+
+        /// Apply the given function to each binding in the hash table 
+        member Iterate : ('T -> unit) -> unit
+
+        interface IEnumerable<'T> 
+        interface System.Collections.IEnumerable 
+
+    type HashSet<'T when 'T : equality> = HashSet<'T, IEqualityComparer<'T>>    
--- fsharp-3.1.1.26+dfsg2.orig/FSharp.PowerPack/math/INumeric.fs
+++ fsharp-3.1.1.26+dfsg2/FSharp.PowerPack/math/INumeric.fs
@@ -1,241 +1,241 @@
-// (c) Microsoft Corporation 2005-2009.  
-
-namespace Microsoft.FSharp.Math
-
-open Microsoft.FSharp.Math
-open System
-open System.Numerics
-open System.Globalization
-
-type INumeric<'T> =
-    abstract Zero: 'T
-    abstract One: 'T
-    abstract Add: 'T * 'T -> 'T
-    abstract Subtract: 'T * 'T -> 'T
-    abstract Multiply : 'T * 'T -> 'T
-    abstract Compare : 'T * 'T -> int
-    abstract Equals : 'T * 'T -> bool
-    abstract Negate : 'T -> 'T
-    abstract Sign : 'T -> int
-    abstract Abs : 'T -> 'T
-    abstract ToString : 'T * string * System.IFormatProvider -> string
-    abstract Parse : string * System.Globalization.NumberStyles * System.IFormatProvider -> 'T
-
-type IIntegral<'T> =
-    inherit INumeric<'T>
-    abstract Modulus: 'T * 'T -> 'T
-    abstract Divide : 'T * 'T -> 'T
-    abstract DivRem : 'T * 'T -> 'T * 'T
-    abstract ToBigInt : 'T -> BigInteger
-    abstract OfBigInt : BigInteger -> 'T
-  
-type IFractional<'T> =
-    inherit INumeric<'T>
-    abstract Reciprocal : 'T -> 'T
-    abstract Divide : 'T * 'T -> 'T
-
-type IFloating<'T> =
-    inherit IFractional<'T>
-    abstract Pi : 'T
-    abstract Exp : 'T -> 'T
-    abstract Log : 'T -> 'T
-    abstract Sqrt : 'T -> 'T
-    abstract LogN : 'T * 'T -> 'T
-    abstract Sin : 'T -> 'T
-    abstract Cos : 'T -> 'T
-    abstract Tan : 'T -> 'T
-    abstract Asin : 'T -> 'T
-    abstract Acos : 'T -> 'T
-    abstract Atan : 'T -> 'T
-    abstract Atan2 : 'T * 'T -> 'T
-    abstract Sinh : 'T -> 'T
-    abstract Cosh : 'T -> 'T
-    abstract Tanh : 'T -> 'T
-
-type IIEEE<'T> =
-    inherit IFloating<'T>
-    abstract PositiveInfinity : 'T
-    abstract NegativeInfinity : 'T
-    abstract NaN              : 'T
-    abstract EpsilonOne          : 'T
-    abstract IsNaN: 'T -> bool 
-    abstract IsInfinite : 'T -> bool 
-
-type INormFloat<'T> =
-    abstract Norm : 'T -> float
- 
-module Instances = 
-  let Int32Numerics = 
-    { new IIntegral<int32> with 
-         member __.Zero = 0
-         member __.One = 1
-         member __.Add(a,b) = a + b
-         member __.Subtract(a,b) = a - b
-         member __.Multiply(a,b) = a * b
-         member __.Equals(a,b) = (a = b)
-         member __.Compare(a,b) = compare a b
-         member __.Negate(a) = - a 
-         member __.Abs(a) = a
-         member __.ToBigInt(a) = new BigInteger(a)
-         member __.OfBigInt(a) = int32 a
-         member __.Sign(a) = Math.Sign(a)
-         member __.Modulus(a,b) = a % b
-         member __.Divide(a,b) = a / b
-         member __.DivRem(a,b) = (a / b, a % b)
-         member __.ToString((x:int32),fmt,fmtprovider) = 
-                x.ToString(fmt,fmtprovider) 
-         member __.Parse(s,numstyle,fmtprovider) = 
-                System.Int32.Parse(s,numstyle,fmtprovider)
-      interface INormFloat<int32> with  
-         member __.Norm(x) = float (abs x)
-    }
-  let Int64Numerics = 
-    { new IIntegral<int64> with 
-         member __.Zero =0L
-         member __.One = 1L
-         member __.Add(a,b) = a + b
-         member __.Subtract(a,b) = a - b
-         member __.Multiply(a,b) = a * b
-         member __.Negate(a) = - a 
-         member __.Abs(a) = Math.Abs(a)
-         member __.ToBigInt(a) = new BigInteger(a)
-         member __.OfBigInt(a) = int64 a
-         member __.Sign(a) = Math.Sign(a)
-         member __.Modulus(a,b) = a % b
-         member __.Equals(a,b) = (a = b)
-         member __.Compare(a,b) = compare a b
-         member __.Divide(a,b) = a / b
-         member __.DivRem(a,b) = (a / b, a % b)
-         member __.ToString((x:int64),fmt,fmtprovider) = x.ToString(fmt,fmtprovider) 
-         member __.Parse(s,numstyle,fmtprovider) = System.Int64.Parse(s,numstyle,fmtprovider)
-      interface INormFloat<int64> with
-         member __.Norm(x) = float (Math.Abs x)
-    }
-  let FloatNumerics = 
-    { new IIEEE<float> with 
-         member __.Zero = 0.0
-         member __.One =  1.0
-         member __.Add(a,b) =  a + b
-         member __.Subtract(a,b) = a - b
-         member __.Multiply(a,b) = a * b
-         member __.Equals(a,b) = (a = b)
-         member __.Compare(a,b) = compare a b
-         member __.PositiveInfinity = Double.PositiveInfinity
-         member __.NegativeInfinity = Double.NegativeInfinity
-         member __.NaN = Double.NaN
-         member __.EpsilonOne = 0x3CB0000000000000LF
-         member __.IsInfinite(a) = Double.IsInfinity(a)
-         member __.IsNaN(a) = Double.IsNaN(a)
-         member __.Pi = Math.PI
-         member __.Reciprocal(a) = 1.0/a
-         member __.Abs(a) = Math.Abs(a)
-         member __.Sign(a) = Math.Sign(a)
-         member __.Asin(a) = Math.Asin(a)
-         member __.Acos(a) = Math.Acos(a)
-         member __.Atan(a) = Math.Atan(a)
-         member __.Atan2(a,b) = Math.Atan2(a,b)
-         member __.Tanh(a) = Math.Tanh(a)
-         member __.Tan(a) = Math.Tan(a)
-         member __.Sqrt(a) = Math.Sqrt(a)
-         member __.Sinh(a) = Math.Sinh(a)
-         member __.Cosh(a) = Math.Cosh(a)
-         member __.Sin(a) = Math.Sin(a)
-         member __.Cos(a) = Math.Cos(a)
-         member __.LogN(a,n) = 
-#if FX_NO_LOGN
-             raise (System.NotSupportedException("this operation is not supported on this platform"))
-#else
-             Math.Log(a,n)
-#endif
-         member __.Log(a) = Math.Log(a)
-         member __.Exp(a) = Math.Exp(a)
-         member __.Negate(a) = -a 
-         member __.Divide(a,b) = a / b
-         member __.ToString((x:float),fmt,fmtprovider) = x.ToString(fmt,fmtprovider) 
-         member __.Parse(s,numstyle,fmtprovider) = System.Double.Parse(s,numstyle,fmtprovider)
-      interface INormFloat<float> with
-          member __.Norm(x) = float (Math.Abs x)
-    }
-  let Float32Numerics = 
-    { new IFractional<float32> with
-           member __.Zero = 0.0f
-           member __.One =  1.0f
-           member __.Add(a,b) = a + b
-           member __.Subtract(a,b) = a - b
-           member __.Multiply(a,b) = a * b
-           member __.Equals(a,b) = (a = b)
-           member __.Compare(a,b) = compare a b
-           member __.Negate(a) = -a 
-           member __.Reciprocal(a) = 1.0f/a
-           member __.Sign(a) = Math.Sign(a)
-           member __.Abs(a) = Math.Abs(a)
-           member __.Divide(a,b) = a / b
-           member __.ToString((x:float32),fmt,fmtprovider) = x.ToString(fmt,fmtprovider) 
-           member __.Parse(s,numstyle,fmtprovider) = System.Single.Parse(s,numstyle,fmtprovider)
-       interface INormFloat<float32> with  
-           member __.Norm(x) = float (Math.Abs x)
-    }
-
-  let BigRationalNumerics = 
-    { new IFractional<bignum> with 
-         member __.Zero = BigRational.Zero
-         member __.One = BigRational.One
-         member __.Add(a,b)      = a + b
-         member __.Subtract(a,b) = a - b
-         member __.Multiply(a,b) = a * b
-         member __.Equals(a,b) = (a = b)
-         member __.Compare(a,b) = compare a b
-         member __.Divide(a,b)   = a / b
-         member __.Abs(a) = BigRational.Abs a
-         member __.Sign(a) = a.Sign
-         member __.Negate(a) = - a 
-         member __.Reciprocal(a) = BigRational.One / a 
-         // Note, this ignores fmt, fmtprovider
-         member __.ToString((x:bignum),fmt,fmtprovider) = x.ToString()
-         // Note, this ignroes numstyle, fmtprovider
-         member __.Parse(s,numstyle,fmtprovider) = BigRational.Parse(s)
-
-      interface INormFloat<bignum> with
-         member __.Norm(x) = float (BigRational.Abs x)
-    }       
-
-  let BigIntNumerics = 
-    let ZeroI = new BigInteger(0)
-    { new IIntegral<_> with 
-         member __.Zero = BigInteger.Zero
-         member __.One =  BigInteger.One
-         member __.Add(a,b) = a + b
-         member __.Subtract(a,b) = a - b
-         member __.Multiply(a,b) = a * b
-         member __.Equals(a,b) = (a = b)
-         member __.Compare(a,b) = compare a b
-         member __.Divide(a,b) = a / b
-         member __.Negate(a) = -a 
-         member __.Modulus(a,b) = a % b
-         member __.DivRem(a,b) = 
-            let mutable r = new BigInteger(0)
-            (BigInteger.DivRem (a,b,&r),r)
-         member __.Sign(a) = a.Sign
-         member __.Abs(a) = abs a
-         member __.ToBigInt(a) = a 
-         member __.OfBigInt(a) = a 
-         
-         member __.ToString(x,fmt,fmtprovider) = 
-#if FX_ATLEAST_40
-             x.ToString(fmt,fmtprovider) 
-#else
-             // Note: this ignores fmt and fmtprovider
-             x.ToString() 
-#endif
-         // Note: this ignores fmt and fmtprovider
-         member __.Parse(s,numstyle,fmtprovider) = 
-#if FX_ATLEAST_40
-             BigInteger.Parse(s,numstyle,fmtprovider)
-#else
-             BigInteger.Parse(s)
-#endif
-
-      interface INormFloat<BigInteger> with  
-         member __.Norm(x) = float (abs x)
-    }       
-
+// (c) Microsoft Corporation 2005-2009.  
+
+namespace Microsoft.FSharp.Math
+
+open Microsoft.FSharp.Math
+open System
+open System.Numerics
+open System.Globalization
+
+type INumeric<'T> =
+    abstract Zero: 'T
+    abstract One: 'T
+    abstract Add: 'T * 'T -> 'T
+    abstract Subtract: 'T * 'T -> 'T
+    abstract Multiply : 'T * 'T -> 'T
+    abstract Compare : 'T * 'T -> int
+    abstract Equals : 'T * 'T -> bool
+    abstract Negate : 'T -> 'T
+    abstract Sign : 'T -> int
+    abstract Abs : 'T -> 'T
+    abstract ToString : 'T * string * System.IFormatProvider -> string
+    abstract Parse : string * System.Globalization.NumberStyles * System.IFormatProvider -> 'T
+
+type IIntegral<'T> =
+    inherit INumeric<'T>
+    abstract Modulus: 'T * 'T -> 'T
+    abstract Divide : 'T * 'T -> 'T
+    abstract DivRem : 'T * 'T -> 'T * 'T
+    abstract ToBigInt : 'T -> BigInteger
+    abstract OfBigInt : BigInteger -> 'T
+  
+type IFractional<'T> =
+    inherit INumeric<'T>
+    abstract Reciprocal : 'T -> 'T
+    abstract Divide : 'T * 'T -> 'T
+
+type IFloating<'T> =
+    inherit IFractional<'T>
+    abstract Pi : 'T
+    abstract Exp : 'T -> 'T
+    abstract Log : 'T -> 'T
+    abstract Sqrt : 'T -> 'T
+    abstract LogN : 'T * 'T -> 'T
+    abstract Sin : 'T -> 'T
+    abstract Cos : 'T -> 'T
+    abstract Tan : 'T -> 'T
+    abstract Asin : 'T -> 'T
+    abstract Acos : 'T -> 'T
+    abstract Atan : 'T -> 'T
+    abstract Atan2 : 'T * 'T -> 'T
+    abstract Sinh : 'T -> 'T
+    abstract Cosh : 'T -> 'T
+    abstract Tanh : 'T -> 'T
+
+type IIEEE<'T> =
+    inherit IFloating<'T>
+    abstract PositiveInfinity : 'T
+    abstract NegativeInfinity : 'T
+    abstract NaN              : 'T
+    abstract EpsilonOne          : 'T
+    abstract IsNaN: 'T -> bool 
+    abstract IsInfinite : 'T -> bool 
+
+type INormFloat<'T> =
+    abstract Norm : 'T -> float
+ 
+module Instances = 
+  let Int32Numerics = 
+    { new IIntegral<int32> with 
+         member __.Zero = 0
+         member __.One = 1
+         member __.Add(a,b) = a + b
+         member __.Subtract(a,b) = a - b
+         member __.Multiply(a,b) = a * b
+         member __.Equals(a,b) = (a = b)
+         member __.Compare(a,b) = compare a b
+         member __.Negate(a) = - a 
+         member __.Abs(a) = a
+         member __.ToBigInt(a) = new BigInteger(a)
+         member __.OfBigInt(a) = int32 a
+         member __.Sign(a) = Math.Sign(a)
+         member __.Modulus(a,b) = a % b
+         member __.Divide(a,b) = a / b
+         member __.DivRem(a,b) = (a / b, a % b)
+         member __.ToString((x:int32),fmt,fmtprovider) = 
+                x.ToString(fmt,fmtprovider) 
+         member __.Parse(s,numstyle,fmtprovider) = 
+                System.Int32.Parse(s,numstyle,fmtprovider)
+      interface INormFloat<int32> with  
+         member __.Norm(x) = float (abs x)
+    }
+  let Int64Numerics = 
+    { new IIntegral<int64> with 
+         member __.Zero =0L
+         member __.One = 1L
+         member __.Add(a,b) = a + b
+         member __.Subtract(a,b) = a - b
+         member __.Multiply(a,b) = a * b
+         member __.Negate(a) = - a 
+         member __.Abs(a) = Math.Abs(a)
+         member __.ToBigInt(a) = new BigInteger(a)
+         member __.OfBigInt(a) = int64 a
+         member __.Sign(a) = Math.Sign(a)
+         member __.Modulus(a,b) = a % b
+         member __.Equals(a,b) = (a = b)
+         member __.Compare(a,b) = compare a b
+         member __.Divide(a,b) = a / b
+         member __.DivRem(a,b) = (a / b, a % b)
+         member __.ToString((x:int64),fmt,fmtprovider) = x.ToString(fmt,fmtprovider) 
+         member __.Parse(s,numstyle,fmtprovider) = System.Int64.Parse(s,numstyle,fmtprovider)
+      interface INormFloat<int64> with
+         member __.Norm(x) = float (Math.Abs x)
+    }
+  let FloatNumerics = 
+    { new IIEEE<float> with 
+         member __.Zero = 0.0
+         member __.One =  1.0
+         member __.Add(a,b) =  a + b
+         member __.Subtract(a,b) = a - b
+         member __.Multiply(a,b) = a * b
+         member __.Equals(a,b) = (a = b)
+         member __.Compare(a,b) = compare a b
+         member __.PositiveInfinity = Double.PositiveInfinity
+         member __.NegativeInfinity = Double.NegativeInfinity
+         member __.NaN = Double.NaN
+         member __.EpsilonOne = 0x3CB0000000000000LF
+         member __.IsInfinite(a) = Double.IsInfinity(a)
+         member __.IsNaN(a) = Double.IsNaN(a)
+         member __.Pi = Math.PI
+         member __.Reciprocal(a) = 1.0/a
+         member __.Abs(a) = Math.Abs(a)
+         member __.Sign(a) = Math.Sign(a)
+         member __.Asin(a) = Math.Asin(a)
+         member __.Acos(a) = Math.Acos(a)
+         member __.Atan(a) = Math.Atan(a)
+         member __.Atan2(a,b) = Math.Atan2(a,b)
+         member __.Tanh(a) = Math.Tanh(a)
+         member __.Tan(a) = Math.Tan(a)
+         member __.Sqrt(a) = Math.Sqrt(a)
+         member __.Sinh(a) = Math.Sinh(a)
+         member __.Cosh(a) = Math.Cosh(a)
+         member __.Sin(a) = Math.Sin(a)
+         member __.Cos(a) = Math.Cos(a)
+         member __.LogN(a,n) = 
+#if FX_NO_LOGN
+             raise (System.NotSupportedException("this operation is not supported on this platform"))
+#else
+             Math.Log(a,n)
+#endif
+         member __.Log(a) = Math.Log(a)
+         member __.Exp(a) = Math.Exp(a)
+         member __.Negate(a) = -a 
+         member __.Divide(a,b) = a / b
+         member __.ToString((x:float),fmt,fmtprovider) = x.ToString(fmt,fmtprovider) 
+         member __.Parse(s,numstyle,fmtprovider) = System.Double.Parse(s,numstyle,fmtprovider)
+      interface INormFloat<float> with
+          member __.Norm(x) = float (Math.Abs x)
+    }
+  let Float32Numerics = 
+    { new IFractional<float32> with
+           member __.Zero = 0.0f
+           member __.One =  1.0f
+           member __.Add(a,b) = a + b
+           member __.Subtract(a,b) = a - b
+           member __.Multiply(a,b) = a * b
+           member __.Equals(a,b) = (a = b)
+           member __.Compare(a,b) = compare a b
+           member __.Negate(a) = -a 
+           member __.Reciprocal(a) = 1.0f/a
+           member __.Sign(a) = Math.Sign(a)
+           member __.Abs(a) = Math.Abs(a)
+           member __.Divide(a,b) = a / b
+           member __.ToString((x:float32),fmt,fmtprovider) = x.ToString(fmt,fmtprovider) 
+           member __.Parse(s,numstyle,fmtprovider) = System.Single.Parse(s,numstyle,fmtprovider)
+       interface INormFloat<float32> with  
+           member __.Norm(x) = float (Math.Abs x)
+    }
+
+  let BigRationalNumerics = 
+    { new IFractional<bignum> with 
+         member __.Zero = BigRational.Zero
+         member __.One = BigRational.One
+         member __.Add(a,b)      = a + b
+         member __.Subtract(a,b) = a - b
+         member __.Multiply(a,b) = a * b
+         member __.Equals(a,b) = (a = b)
+         member __.Compare(a,b) = compare a b
+         member __.Divide(a,b)   = a / b
+         member __.Abs(a) = BigRational.Abs a
+         member __.Sign(a) = a.Sign
+         member __.Negate(a) = - a 
+         member __.Reciprocal(a) = BigRational.One / a 
+         // Note, this ignores fmt, fmtprovider
+         member __.ToString((x:bignum),fmt,fmtprovider) = x.ToString()
+         // Note, this ignroes numstyle, fmtprovider
+         member __.Parse(s,numstyle,fmtprovider) = BigRational.Parse(s)
+
+      interface INormFloat<bignum> with
+         member __.Norm(x) = float (BigRational.Abs x)
+    }       
+
+  let BigIntNumerics = 
+    let ZeroI = new BigInteger(0)
+    { new IIntegral<_> with 
+         member __.Zero = BigInteger.Zero
+         member __.One =  BigInteger.One
+         member __.Add(a,b) = a + b
+         member __.Subtract(a,b) = a - b
+         member __.Multiply(a,b) = a * b
+         member __.Equals(a,b) = (a = b)
+         member __.Compare(a,b) = compare a b
+         member __.Divide(a,b) = a / b
+         member __.Negate(a) = -a 
+         member __.Modulus(a,b) = a % b
+         member __.DivRem(a,b) = 
+            let mutable r = new BigInteger(0)
+            (BigInteger.DivRem (a,b,&r),r)
+         member __.Sign(a) = a.Sign
+         member __.Abs(a) = abs a
+         member __.ToBigInt(a) = a 
+         member __.OfBigInt(a) = a 
+         
+         member __.ToString(x,fmt,fmtprovider) = 
+#if FX_ATLEAST_40
+             x.ToString(fmt,fmtprovider) 
+#else
+             // Note: this ignores fmt and fmtprovider
+             x.ToString() 
+#endif
+         // Note: this ignores fmt and fmtprovider
+         member __.Parse(s,numstyle,fmtprovider) = 
+#if FX_ATLEAST_40
+             BigInteger.Parse(s,numstyle,fmtprovider)
+#else
+             BigInteger.Parse(s)
+#endif
+
+      interface INormFloat<BigInteger> with  
+         member __.Norm(x) = float (abs x)
+    }       
+
--- fsharp-3.1.1.26+dfsg2.orig/FSharp.PowerPack/math/INumeric.fsi
+++ fsharp-3.1.1.26+dfsg2/FSharp.PowerPack/math/INumeric.fsi
@@ -1,82 +1,82 @@
-// (c) Microsoft Corporation 2005-2009. 
-namespace Microsoft.FSharp.Math
-
-open Microsoft.FSharp.Math
-open System.Numerics
-open System
-
-// A type-class for numeric types
-type INumeric<'T> =
-    abstract Zero: 'T
-    abstract One: 'T
-    abstract Add: 'T * 'T -> 'T
-    abstract Equals : 'T * 'T -> bool
-    abstract Compare : 'T * 'T -> int
-    abstract Subtract: 'T * 'T -> 'T
-    abstract Multiply : 'T * 'T -> 'T
-    abstract Negate : 'T -> 'T
-    abstract Sign : 'T -> int
-    abstract Abs : 'T -> 'T    
-    abstract ToString : 'T * string * System.IFormatProvider -> string
-    abstract Parse : string * System.Globalization.NumberStyles * System.IFormatProvider -> 'T
-
-type IIntegral<'T> =
-    inherit INumeric<'T>
-    abstract Modulus: 'T * 'T -> 'T
-    abstract Divide : 'T * 'T -> 'T
-    abstract DivRem : 'T * 'T -> 'T * 'T
-    abstract ToBigInt : 'T -> BigInteger
-    abstract OfBigInt : BigInteger -> 'T
-  
-type IFractional<'T> =
-    inherit INumeric<'T>
-    abstract Reciprocal : 'T -> 'T
-    abstract Divide : 'T * 'T -> 'T
-
-// Suggestion: IReal (since transcendentals are added here).
-type IFloating<'T> =
-    inherit IFractional<'T>
-    abstract Pi : 'T
-    abstract Exp : 'T -> 'T
-    abstract Log : 'T -> 'T
-    abstract Sqrt : 'T -> 'T
-    abstract LogN : 'T * 'T -> 'T
-    abstract Sin : 'T -> 'T
-    abstract Cos : 'T -> 'T
-    abstract Tan : 'T -> 'T
-    abstract Asin : 'T -> 'T
-    abstract Acos : 'T -> 'T
-    abstract Atan : 'T -> 'T
-    abstract Atan2 : 'T * 'T -> 'T
-    abstract Sinh : 'T -> 'T
-    abstract Cosh : 'T -> 'T
-    abstract Tanh : 'T -> 'T
-
-type INormFloat<'T> =
-    abstract Norm : 'T -> float
-  
-// Direct access to IEEE encoding not easy on .NET
-type IIEEE<'T> =
-    inherit IFloating<'T>
-    abstract PositiveInfinity : 'T
-    abstract NegativeInfinity : 'T
-    abstract NaN              : 'T
-    abstract EpsilonOne       : 'T
-
-    abstract IsNaN: 'T -> bool 
-    abstract IsInfinite : 'T -> bool 
-    //abstract IsDenormalized   : 'T -> bool 
-    //abstract IsNegativeZero   : 'T -> bool 
-    //abstract IsIEEE           : 'T -> bool 
-
-
-module Instances =
-    val Float32Numerics  : IFractional<float32> 
-    val FloatNumerics    : IIEEE<float>
-    val Int32Numerics    : IIntegral<int32>
-    val Int64Numerics    : IIntegral<int64>
-    val BigIntNumerics   : IIntegral<BigInteger>
-    val BigRationalNumerics   : IFractional<bignum>  
-
-
-
+// (c) Microsoft Corporation 2005-2009. 
+namespace Microsoft.FSharp.Math
+
+open Microsoft.FSharp.Math
+open System.Numerics
+open System
+
+// A type-class for numeric types
+type INumeric<'T> =
+    abstract Zero: 'T
+    abstract One: 'T
+    abstract Add: 'T * 'T -> 'T
+    abstract Equals : 'T * 'T -> bool
+    abstract Compare : 'T * 'T -> int
+    abstract Subtract: 'T * 'T -> 'T
+    abstract Multiply : 'T * 'T -> 'T
+    abstract Negate : 'T -> 'T
+    abstract Sign : 'T -> int
+    abstract Abs : 'T -> 'T    
+    abstract ToString : 'T * string * System.IFormatProvider -> string
+    abstract Parse : string * System.Globalization.NumberStyles * System.IFormatProvider -> 'T
+
+type IIntegral<'T> =
+    inherit INumeric<'T>
+    abstract Modulus: 'T * 'T -> 'T
+    abstract Divide : 'T * 'T -> 'T
+    abstract DivRem : 'T * 'T -> 'T * 'T
+    abstract ToBigInt : 'T -> BigInteger
+    abstract OfBigInt : BigInteger -> 'T
+  
+type IFractional<'T> =
+    inherit INumeric<'T>
+    abstract Reciprocal : 'T -> 'T
+    abstract Divide : 'T * 'T -> 'T
+
+// Suggestion: IReal (since transcendentals are added here).
+type IFloating<'T> =
+    inherit IFractional<'T>
+    abstract Pi : 'T
+    abstract Exp : 'T -> 'T
+    abstract Log : 'T -> 'T
+    abstract Sqrt : 'T -> 'T
+    abstract LogN : 'T * 'T -> 'T
+    abstract Sin : 'T -> 'T
+    abstract Cos : 'T -> 'T
+    abstract Tan : 'T -> 'T
+    abstract Asin : 'T -> 'T
+    abstract Acos : 'T -> 'T
+    abstract Atan : 'T -> 'T
+    abstract Atan2 : 'T * 'T -> 'T
+    abstract Sinh : 'T -> 'T
+    abstract Cosh : 'T -> 'T
+    abstract Tanh : 'T -> 'T
+
+type INormFloat<'T> =
+    abstract Norm : 'T -> float
+  
+// Direct access to IEEE encoding not easy on .NET
+type IIEEE<'T> =
+    inherit IFloating<'T>
+    abstract PositiveInfinity : 'T
+    abstract NegativeInfinity : 'T
+    abstract NaN              : 'T
+    abstract EpsilonOne       : 'T
+
+    abstract IsNaN: 'T -> bool 
+    abstract IsInfinite : 'T -> bool 
+    //abstract IsDenormalized   : 'T -> bool 
+    //abstract IsNegativeZero   : 'T -> bool 
+    //abstract IsIEEE           : 'T -> bool 
+
+
+module Instances =
+    val Float32Numerics  : IFractional<float32> 
+    val FloatNumerics    : IIEEE<float>
+    val Int32Numerics    : IIntegral<int32>
+    val Int64Numerics    : IIntegral<int64>
+    val BigIntNumerics   : IIntegral<BigInteger>
+    val BigRationalNumerics   : IFractional<bignum>  
+
+
+
--- fsharp-3.1.1.26+dfsg2.orig/FSharp.PowerPack/math/NativeArrayExtensions.fs
+++ fsharp-3.1.1.26+dfsg2/FSharp.PowerPack/math/NativeArrayExtensions.fs
@@ -1,51 +1,51 @@
-// (c) Microsoft Corporation 2005-2009.
-
-namespace Microsoft.FSharp.NativeInterop
-
-#nowarn "44"
-#nowarn "9" // unverifiable constructs
-#nowarn "51" // unverifiable constructs
-
-open System
-open System.Runtime.InteropServices
-open Microsoft.FSharp.NativeInterop
-open Microsoft.FSharp.Math
-
-[<AutoOpen>]
-module NativArrayExtensionsForMatrix =
-
-    [<NoDynamicInvocation>]
-    let inline pinObjUnscoped (obj: obj) =  GCHandle.Alloc(obj,GCHandleType.Pinned) 
-    [<NoDynamicInvocation>]
-    let inline pinObj (obj: obj) f = 
-        let gch = pinObjUnscoped obj 
-        try f gch
-        finally
-            gch.Free()
-
-    type Microsoft.FSharp.NativeInterop.PinnedArray<'T when 'T : unmanaged> with
-
-        [<NoDynamicInvocation>]
-        static member inline of_vector(m:Vector<'T>) = 
-            let gch = pinObjUnscoped (box m.InternalValues) 
-            let ptr = &&m.InternalValues.[0]
-            new PinnedArray<'T>(new NativeArray<_>(ptr,m.Length),gch)
-
-        [<NoDynamicInvocation>]
-        static member inline of_rowvec(m:RowVector<'T>) = 
-            let gch = pinObjUnscoped (box m.InternalValues) 
-            let ptr = &&m.InternalValues.[0]
-            new PinnedArray<'T>(new NativeArray<_>(ptr,m.Length),gch)
-            
-
-    type Microsoft.FSharp.NativeInterop.PinnedArray2<'T when 'T : unmanaged> with
-
-        [<NoDynamicInvocation>]
-        static member inline of_matrix(m:Matrix<'T>) = 
-            if m.IsDense then
-                let gch = pinObjUnscoped (box m.InternalDenseValues) 
-                let ptr = && m.InternalDenseValues.[0,0]
-                new PinnedArray2<'T>(new NativeArray2<_>(ptr,m.NumRows,m.NumCols),gch) 
-            else
-                invalidArg "m" "cannot pin sparse matrices"
-            
+// (c) Microsoft Corporation 2005-2009.
+
+namespace Microsoft.FSharp.NativeInterop
+
+#nowarn "44"
+#nowarn "9" // unverifiable constructs
+#nowarn "51" // unverifiable constructs
+
+open System
+open System.Runtime.InteropServices
+open Microsoft.FSharp.NativeInterop
+open Microsoft.FSharp.Math
+
+[<AutoOpen>]
+module NativArrayExtensionsForMatrix =
+
+    [<NoDynamicInvocation>]
+    let inline pinObjUnscoped (obj: obj) =  GCHandle.Alloc(obj,GCHandleType.Pinned) 
+    [<NoDynamicInvocation>]
+    let inline pinObj (obj: obj) f = 
+        let gch = pinObjUnscoped obj 
+        try f gch
+        finally
+            gch.Free()
+
+    type Microsoft.FSharp.NativeInterop.PinnedArray<'T when 'T : unmanaged> with
+
+        [<NoDynamicInvocation>]
+        static member inline of_vector(m:Vector<'T>) = 
+            let gch = pinObjUnscoped (box m.InternalValues) 
+            let ptr = &&m.InternalValues.[0]
+            new PinnedArray<'T>(new NativeArray<_>(ptr,m.Length),gch)
+
+        [<NoDynamicInvocation>]
+        static member inline of_rowvec(m:RowVector<'T>) = 
+            let gch = pinObjUnscoped (box m.InternalValues) 
+            let ptr = &&m.InternalValues.[0]
+            new PinnedArray<'T>(new NativeArray<_>(ptr,m.Length),gch)
+            
+
+    type Microsoft.FSharp.NativeInterop.PinnedArray2<'T when 'T : unmanaged> with
+
+        [<NoDynamicInvocation>]
+        static member inline of_matrix(m:Matrix<'T>) = 
+            if m.IsDense then
+                let gch = pinObjUnscoped (box m.InternalDenseValues) 
+                let ptr = && m.InternalDenseValues.[0,0]
+                new PinnedArray2<'T>(new NativeArray2<_>(ptr,m.NumRows,m.NumCols),gch) 
+            else
+                invalidArg "m" "cannot pin sparse matrices"
+            
--- fsharp-3.1.1.26+dfsg2.orig/FSharp.PowerPack/math/NativeArrayExtensions.fsi
+++ fsharp-3.1.1.26+dfsg2/FSharp.PowerPack/math/NativeArrayExtensions.fsi
@@ -1,27 +1,27 @@
-// (c) Microsoft Corporation 2005-2009. 
-
-namespace Microsoft.FSharp.NativeInterop
-
-open Microsoft.FSharp.Math
-open System.Runtime.InteropServices
-
-[<AutoOpen>]
-module NativArrayExtensionsForMatrix =
-
-    type Microsoft.FSharp.NativeInterop.PinnedArray<'T when 'T : unmanaged> with
-
-        /// For native interop. Pin the given object
-        [<NoDynamicInvocation>]
-        static member inline of_vector : Vector<'T> -> PinnedArray<'T>
-
-        /// For native interop. Pin the given object
-        [<NoDynamicInvocation>]
-        static member inline of_rowvec : RowVector<'T> -> PinnedArray<'T>
-
-
-    type Microsoft.FSharp.NativeInterop.PinnedArray2<'T when 'T : unmanaged> with
-
-        /// For native interop. Pin the given object
-        [<NoDynamicInvocation>]
-        static member inline of_matrix : Matrix<'T> -> PinnedArray2<'T>
-
+// (c) Microsoft Corporation 2005-2009. 
+
+namespace Microsoft.FSharp.NativeInterop
+
+open Microsoft.FSharp.Math
+open System.Runtime.InteropServices
+
+[<AutoOpen>]
+module NativArrayExtensionsForMatrix =
+
+    type Microsoft.FSharp.NativeInterop.PinnedArray<'T when 'T : unmanaged> with
+
+        /// For native interop. Pin the given object
+        [<NoDynamicInvocation>]
+        static member inline of_vector : Vector<'T> -> PinnedArray<'T>
+
+        /// For native interop. Pin the given object
+        [<NoDynamicInvocation>]
+        static member inline of_rowvec : RowVector<'T> -> PinnedArray<'T>
+
+
+    type Microsoft.FSharp.NativeInterop.PinnedArray2<'T when 'T : unmanaged> with
+
+        /// For native interop. Pin the given object
+        [<NoDynamicInvocation>]
+        static member inline of_matrix : Matrix<'T> -> PinnedArray2<'T>
+
--- fsharp-3.1.1.26+dfsg2.orig/FSharp.PowerPack/math/associations.fs
+++ fsharp-3.1.1.26+dfsg2/FSharp.PowerPack/math/associations.fs
@@ -1,61 +1,61 @@
-// (c) Microsoft Corporation 2005-2009. 
-
-namespace Microsoft.FSharp.Math
-
-module GlobalAssociations =
-
-    open Microsoft.FSharp.Math
-    open Microsoft.FSharp.Math.Instances
-    open System
-    open System.Numerics
-
-    let ComplexNumerics = 
-      { new IFractional<_> with 
-          member __.Zero = Microsoft.FSharp.Math.Complex.Zero
-          member __.One = Microsoft.FSharp.Math.Complex.One
-          member __.Add(a,b) = a + b
-          member __.Subtract(a,b) = a - b
-          member __.Multiply(a,b) = a * b
-          member __.Equals(a,b) = (a = b)
-          member __.Compare(a,b) = compare a b
-          member __.Divide(a,b) = a / b
-          member __.Negate(a) = -a
-          member __.Abs(a)  = a // not signed
-          member __.Sign(a) = 1 // not signed
-          member __.Reciprocal(a) =  Microsoft.FSharp.Math.Complex.One / a 
-          member __.ToString((x:Microsoft.FSharp.Math.Complex),fmt,fmtprovider) = x.ToString(fmt,fmtprovider)
-          member __.Parse(s,numstyle,fmtprovider) = Microsoft.FSharp.Math.Complex.mkRect (System.Double.Parse(s,numstyle,fmtprovider),0.0) }
-
-    let ht = 
-        let ht = new System.Collections.Generic.Dictionary<Type,obj>() 
-        let optab =
-            [ typeof<float>,   (Some(FloatNumerics    :> INumeric<float>) :> obj);
-              typeof<int32>,   (Some(Int32Numerics    :> INumeric<int32>) :> obj);
-              typeof<int64>,   (Some(Int64Numerics    :> INumeric<int64>) :> obj);
-              typeof<BigInteger>,  (Some(BigIntNumerics   :> INumeric<BigInteger>) :> obj);
-              typeof<float32>, (Some(Float32Numerics  :> INumeric<float32>) :> obj);
-              typeof<Microsoft.FSharp.Math.Complex>, (Some(ComplexNumerics :> INumeric<Microsoft.FSharp.Math.Complex>) :> obj);
-              typeof<bignum>,  (Some(BigRationalNumerics   :> INumeric<bignum>) :> obj); ]
-           
-        List.iter (fun (ty,ops) -> ht.Add(ty,ops)) optab;
-        ht
-        
-    let Put (ty: System.Type, d : obj)  =
-        lock ht (fun () -> 
-            if ht.ContainsKey(ty) then invalidArg "ty" ("the type "+ty.Name+" already has a registered numeric association");
-            ht.Add(ty, d))
-      
-    let TryGetNumericAssociation<'a>() = 
-        lock ht (fun () -> 
-            let ty = typeof<'a>  
-            if ht.ContainsKey(ty) then
-                match ht.[ty] with
-                | :? (INumeric<'a> option) as r -> r
-                | _ -> invalidArg "ty" ("The type "+ty.Name+" has a numeric association but it was not of the correct type")
-            else
-                None)
-
-    let GetNumericAssociation() = (TryGetNumericAssociation()).Value
-    let RegisterNumericAssociation (d : INumeric<'a>)  = Put(typeof<'a>, box(Some d))
-
-
+// (c) Microsoft Corporation 2005-2009. 
+
+namespace Microsoft.FSharp.Math
+
+module GlobalAssociations =
+
+    open Microsoft.FSharp.Math
+    open Microsoft.FSharp.Math.Instances
+    open System
+    open System.Numerics
+
+    let ComplexNumerics = 
+      { new IFractional<_> with 
+          member __.Zero = Microsoft.FSharp.Math.Complex.Zero
+          member __.One = Microsoft.FSharp.Math.Complex.One
+          member __.Add(a,b) = a + b
+          member __.Subtract(a,b) = a - b
+          member __.Multiply(a,b) = a * b
+          member __.Equals(a,b) = (a = b)
+          member __.Compare(a,b) = compare a b
+          member __.Divide(a,b) = a / b
+          member __.Negate(a) = -a
+          member __.Abs(a)  = a // not signed
+          member __.Sign(a) = 1 // not signed
+          member __.Reciprocal(a) =  Microsoft.FSharp.Math.Complex.One / a 
+          member __.ToString((x:Microsoft.FSharp.Math.Complex),fmt,fmtprovider) = x.ToString(fmt,fmtprovider)
+          member __.Parse(s,numstyle,fmtprovider) = Microsoft.FSharp.Math.Complex.mkRect (System.Double.Parse(s,numstyle,fmtprovider),0.0) }
+
+    let ht = 
+        let ht = new System.Collections.Generic.Dictionary<Type,obj>() 
+        let optab =
+            [ typeof<float>,   (Some(FloatNumerics    :> INumeric<float>) :> obj);
+              typeof<int32>,   (Some(Int32Numerics    :> INumeric<int32>) :> obj);
+              typeof<int64>,   (Some(Int64Numerics    :> INumeric<int64>) :> obj);
+              typeof<BigInteger>,  (Some(BigIntNumerics   :> INumeric<BigInteger>) :> obj);
+              typeof<float32>, (Some(Float32Numerics  :> INumeric<float32>) :> obj);
+              typeof<Microsoft.FSharp.Math.Complex>, (Some(ComplexNumerics :> INumeric<Microsoft.FSharp.Math.Complex>) :> obj);
+              typeof<bignum>,  (Some(BigRationalNumerics   :> INumeric<bignum>) :> obj); ]
+           
+        List.iter (fun (ty,ops) -> ht.Add(ty,ops)) optab;
+        ht
+        
+    let Put (ty: System.Type, d : obj)  =
+        lock ht (fun () -> 
+            if ht.ContainsKey(ty) then invalidArg "ty" ("the type "+ty.Name+" already has a registered numeric association");
+            ht.Add(ty, d))
+      
+    let TryGetNumericAssociation<'a>() = 
+        lock ht (fun () -> 
+            let ty = typeof<'a>  
+            if ht.ContainsKey(ty) then
+                match ht.[ty] with
+                | :? (INumeric<'a> option) as r -> r
+                | _ -> invalidArg "ty" ("The type "+ty.Name+" has a numeric association but it was not of the correct type")
+            else
+                None)
+
+    let GetNumericAssociation() = (TryGetNumericAssociation()).Value
+    let RegisterNumericAssociation (d : INumeric<'a>)  = Put(typeof<'a>, box(Some d))
+
+
--- fsharp-3.1.1.26+dfsg2.orig/FSharp.PowerPack/math/associations.fsi
+++ fsharp-3.1.1.26+dfsg2/FSharp.PowerPack/math/associations.fsi
@@ -1,28 +1,28 @@
-// (c) Microsoft Corporation 2005-2009. 
-namespace Microsoft.FSharp.Math
-
-/// Associations are a way of associating dictionaries of
-/// operations with given types at runtime.  Associations are global to a 
-/// .NET application domain.  Once specified an association may not be deleted
-/// or modified.
-///
-/// In this release the system of associations is simply 
-/// limited to a registry of types that support dictionaries (i.e. interface objects)
-/// of numeric operations.  The following types are pre-registered with associated numeric
-/// operations: float, int32, int64, bigint, float32, Complex, bignum.  Other types must be
-/// registered explicitly by user code.
-///
-module GlobalAssociations =
-
-    open Microsoft.FSharp.Math
-
-    /// Attempt to determine a numeric association for the given type, i.e. a registered dictionary of
-    /// numeric operations.  The interface can be queried dynamically for additional functionality in the numerics
-    /// hierarchy.
-    val GetNumericAssociation : unit -> INumeric<'a> 
-
-    val TryGetNumericAssociation : unit -> INumeric<'a>  option
-    /// Record an AppDomain-wide association between the given type and the given dictionary of
-    /// numeric operations.  Raise an error if an existing association already exists. 
-    val RegisterNumericAssociation : INumeric<'a> -> unit
-
+// (c) Microsoft Corporation 2005-2009. 
+namespace Microsoft.FSharp.Math
+
+/// Associations are a way of associating dictionaries of
+/// operations with given types at runtime.  Associations are global to a 
+/// .NET application domain.  Once specified an association may not be deleted
+/// or modified.
+///
+/// In this release the system of associations is simply 
+/// limited to a registry of types that support dictionaries (i.e. interface objects)
+/// of numeric operations.  The following types are pre-registered with associated numeric
+/// operations: float, int32, int64, bigint, float32, Complex, bignum.  Other types must be
+/// registered explicitly by user code.
+///
+module GlobalAssociations =
+
+    open Microsoft.FSharp.Math
+
+    /// Attempt to determine a numeric association for the given type, i.e. a registered dictionary of
+    /// numeric operations.  The interface can be queried dynamically for additional functionality in the numerics
+    /// hierarchy.
+    val GetNumericAssociation : unit -> INumeric<'a> 
+
+    val TryGetNumericAssociation : unit -> INumeric<'a>  option
+    /// Record an AppDomain-wide association between the given type and the given dictionary of
+    /// numeric operations.  Raise an error if an existing association already exists. 
+    val RegisterNumericAssociation : INumeric<'a> -> unit
+
--- fsharp-3.1.1.26+dfsg2.orig/FSharp.PowerPack/math/complex.fs
+++ fsharp-3.1.1.26+dfsg2/FSharp.PowerPack/math/complex.fs
@@ -1,130 +1,130 @@
-// (c) Microsoft Corporation 2005-2009. 
-
-#nowarn "52" // defensive copy of structs warning
-
-namespace Microsoft.FSharp.Math
-
-    open Microsoft.FSharp.Math
-    open System
-    open System.Globalization
-
-    [<Struct>]
-    [<CustomEquality; CustomComparison>]
-    type Complex(real: float, imaginary: float) =
-        //new() = new Complex(0.0,0.0)
-        member x.r = real
-        member x.i = imaginary
-        override x.ToString() = x.ToString("g")
-        member x.ToString(fmt) = x.ToString(fmt,CultureInfo.InvariantCulture)
-        member x.ToString(fmt,fmtprovider:IFormatProvider) = 
-               x.r.ToString(fmt,fmtprovider)+"r"+(if x.i < 0.0 then "-" else "+")+(System.Math.Abs x.i).ToString(fmt,fmtprovider)+"i"
-        interface IComparable with 
-            member x.CompareTo(obj) = 
-                match obj with 
-                | :? Complex as y -> 
-                     let c = compare x.r y.r
-                     if c <> 0 then c else compare x.i y.i
-                | _ -> invalidArg "obj" "not a Complex number"
-        override x.Equals(obj) = 
-                match obj with 
-                | :? Complex as y -> x.r = y.r && x.i = y.i
-                | _ -> false
-        override x.GetHashCode() = 
-                (hash x.r >>> 5) ^^^  (hash x.r <<< 3) ^^^  (((hash x.i >>> 4) ^^^  (hash x.i <<< 4)) + 0x9e3779b9)
-
-                
-    type complex = Complex
-
-    [<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
-    module Complex = 
-      let mkRect(a,b) = new Complex(a,b)
-      let conjugate (c:complex) = mkRect (c.r, -c.i)
-      let mkPolar(a,b) = mkRect (a * Math.Cos(b), a * Math.Sin(b))
-      let cis b = mkPolar(1.0,b)
-      let zero = mkRect(0.,0.)
-      let one = mkRect(1.,0.) 
-      let onei = mkRect(0.,1.) 
-      let magnitude (c:complex) = sqrt(c.r*c.r + c.i*c.i)
-      let phase (c:complex) = Math.Atan2(c.i,c.r)
-      let realPart (c:complex) = c.r
-      let imagPart (c:complex) = c.i  
-      let abs (a:complex) = sqrt (a.r**2.0 + a.i**2.0)
-      let add (a:complex) (b:complex) = mkRect(a.r + b.r, a.i+b.i)
-      let sub (a:complex) (b:complex) = mkRect(a.r - b.r, a.i-b.i)
-      let mul (a:complex) (b:complex) = mkRect(a.r * b.r - a.i * b.i, a.i*b.r + b.i*a.r)
-      let div (x:complex) (y:complex) = 
-          let a = x.r in let b = x.i in 
-          let c = y.r in let d = y.i in 
-          //(a+ib)/(c+id)=(ac+bd+i(bc-ad))/(c2+d2) 
-          let q = c*c + d*d in 
-          mkRect((a*c+b*d)/q, (b*c - a*d)/q)
-      let neg (a:complex) = mkRect(-a.r,-a.i)
-      let smul (a:float)(b:complex) = mkRect(a * b.r, a*b.i)
-      let muls (a:complex) (b:float) = mkRect(a.r *b, a.i*b)
-      let fmt_of_string numstyle fmtprovider (s:string) =
-        mkRect (System.Double.Parse(s,numstyle,fmtprovider),0.0) 
-      let of_string s = fmt_of_string NumberStyles.Any CultureInfo.InvariantCulture s
-
-      // ik.(r + i.th) = -k.th + i.k.r 
-      let iscale k (x:complex) = mkRect (-k * x.i , k * x.r)
-
-      // LogN : 'a * 'a -> 'a
-      // Asin : 'a -> 'a
-      // Acos : 'a -> 'a
-      // Atan : 'a -> 'a
-      // Atan2 : 'a * 'a -> 'a
-      // Sinh : 'a -> 'a
-      // Cosh : 'a -> 'a
-      // Tanh : 'a -> 'a
-
-      let pi    = mkRect (Math.PI,0.0)
-
-      // exp(r+it) = exp(r).(cos(t)+i.sin(t)) - De Moivre Theorem 
-      let exp (x:complex) = smul (exp(x.r)) (mkRect(cos(x.i), sin(x.i)))
-      // x = mag.e^(i.th) = e^ln(mag).e^(i.th) = e^(ln(mag) + i.th) 
-      let log x = mkRect (log(magnitude(x)),phase(x))
-
-      let sqrt x = mkPolar (sqrt(magnitude x),phase x / 2.0)
-
-      // cos(x) = (exp(i.x) + exp(-i.x))/2 
-      let cos x = smul 0.5 (add (exp(iscale 1.0 x)) (exp(iscale -1.0 x)))
-      // sin(x) = (exp(i.x) - exp(-i.x))/2 . (-i) 
-      let sin x = smul 0.5 (sub (exp(iscale 1.0 x)) (exp(iscale -1.0 x))) |> iscale (-1.0)
-      // tan(x) = (exp(i.x) - exp(-i.x)) . (-i) / (exp(i.x) + exp(-i.x)) 
-      //        = (exp(2i.x) - 1.0)      . (-i) / (exp(2i.x) + 1.0)      
-      let tan x = let exp2ix = exp(iscale 2.0 x) in
-                  (div (sub exp2ix one) (add exp2ix one)) |> iscale -1.0
-
-
-    type Complex with 
-        static member Create(a,b) = Complex.mkRect (a,b)
-        static member CreatePolar(a,b) = Complex.mkPolar (a,b)
-        member x.Magnitude = Complex.magnitude x
-        member x.Phase = Complex.phase x
-        member x.RealPart = x.r
-        member x.ImaginaryPart = x.i
-        member x.Conjugate = Complex.conjugate x
-
-        static member Sin(x) = Complex.sin(x)
-        static member Cos(x) = Complex.cos(x)
-        static member Abs(x) = Complex.abs(x)
-        static member Tan(x) = Complex.tan(x)
-        static member Log(x) = Complex.log(x)
-        static member Exp(x) = Complex.exp(x)
-        static member Sqrt(x) = Complex.sqrt(x)
-        
-        static member Zero = Complex.zero
-        static member One = Complex.one 
-        static member OneI = Complex.onei 
-        static member ( +  ) (a,b) = Complex.add a b
-        static member ( -  ) (a,b) = Complex.sub a b
-        static member ( *  ) (a,b) = Complex.mul a b
-        static member ( /  ) (a,b) = Complex.div a b
-        static member ( ~- ) a = Complex.neg a
-        static member ( * ) (a,b) = Complex.smul a b
-        static member ( * ) (a,b) = Complex.muls a b
-
-
-    module ComplexTopLevelOperators = 
-        let complex x y = Complex.mkRect (x,y)
-
+// (c) Microsoft Corporation 2005-2009. 
+
+#nowarn "52" // defensive copy of structs warning
+
+namespace Microsoft.FSharp.Math
+
+    open Microsoft.FSharp.Math
+    open System
+    open System.Globalization
+
+    [<Struct>]
+    [<CustomEquality; CustomComparison>]
+    type Complex(real: float, imaginary: float) =
+        //new() = new Complex(0.0,0.0)
+        member x.r = real
+        member x.i = imaginary
+        override x.ToString() = x.ToString("g")
+        member x.ToString(fmt) = x.ToString(fmt,CultureInfo.InvariantCulture)
+        member x.ToString(fmt,fmtprovider:IFormatProvider) = 
+               x.r.ToString(fmt,fmtprovider)+"r"+(if x.i < 0.0 then "-" else "+")+(System.Math.Abs x.i).ToString(fmt,fmtprovider)+"i"
+        interface IComparable with 
+            member x.CompareTo(obj) = 
+                match obj with 
+                | :? Complex as y -> 
+                     let c = compare x.r y.r
+                     if c <> 0 then c else compare x.i y.i
+                | _ -> invalidArg "obj" "not a Complex number"
+        override x.Equals(obj) = 
+                match obj with 
+                | :? Complex as y -> x.r = y.r && x.i = y.i
+                | _ -> false
+        override x.GetHashCode() = 
+                (hash x.r >>> 5) ^^^  (hash x.r <<< 3) ^^^  (((hash x.i >>> 4) ^^^  (hash x.i <<< 4)) + 0x9e3779b9)
+
+                
+    type complex = Complex
+
+    [<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+    module Complex = 
+      let mkRect(a,b) = new Complex(a,b)
+      let conjugate (c:complex) = mkRect (c.r, -c.i)
+      let mkPolar(a,b) = mkRect (a * Math.Cos(b), a * Math.Sin(b))
+      let cis b = mkPolar(1.0,b)
+      let zero = mkRect(0.,0.)
+      let one = mkRect(1.,0.) 
+      let onei = mkRect(0.,1.) 
+      let magnitude (c:complex) = sqrt(c.r*c.r + c.i*c.i)
+      let phase (c:complex) = Math.Atan2(c.i,c.r)
+      let realPart (c:complex) = c.r
+      let imagPart (c:complex) = c.i  
+      let abs (a:complex) = sqrt (a.r**2.0 + a.i**2.0)
+      let add (a:complex) (b:complex) = mkRect(a.r + b.r, a.i+b.i)
+      let sub (a:complex) (b:complex) = mkRect(a.r - b.r, a.i-b.i)
+      let mul (a:complex) (b:complex) = mkRect(a.r * b.r - a.i * b.i, a.i*b.r + b.i*a.r)
+      let div (x:complex) (y:complex) = 
+          let a = x.r in let b = x.i in 
+          let c = y.r in let d = y.i in 
+          //(a+ib)/(c+id)=(ac+bd+i(bc-ad))/(c2+d2) 
+          let q = c*c + d*d in 
+          mkRect((a*c+b*d)/q, (b*c - a*d)/q)
+      let neg (a:complex) = mkRect(-a.r,-a.i)
+      let smul (a:float)(b:complex) = mkRect(a * b.r, a*b.i)
+      let muls (a:complex) (b:float) = mkRect(a.r *b, a.i*b)
+      let fmt_of_string numstyle fmtprovider (s:string) =
+        mkRect (System.Double.Parse(s,numstyle,fmtprovider),0.0) 
+      let of_string s = fmt_of_string NumberStyles.Any CultureInfo.InvariantCulture s
+
+      // ik.(r + i.th) = -k.th + i.k.r 
+      let iscale k (x:complex) = mkRect (-k * x.i , k * x.r)
+
+      // LogN : 'a * 'a -> 'a
+      // Asin : 'a -> 'a
+      // Acos : 'a -> 'a
+      // Atan : 'a -> 'a
+      // Atan2 : 'a * 'a -> 'a
+      // Sinh : 'a -> 'a
+      // Cosh : 'a -> 'a
+      // Tanh : 'a -> 'a
+
+      let pi    = mkRect (Math.PI,0.0)
+
+      // exp(r+it) = exp(r).(cos(t)+i.sin(t)) - De Moivre Theorem 
+      let exp (x:complex) = smul (exp(x.r)) (mkRect(cos(x.i), sin(x.i)))
+      // x = mag.e^(i.th) = e^ln(mag).e^(i.th) = e^(ln(mag) + i.th) 
+      let log x = mkRect (log(magnitude(x)),phase(x))
+
+      let sqrt x = mkPolar (sqrt(magnitude x),phase x / 2.0)
+
+      // cos(x) = (exp(i.x) + exp(-i.x))/2 
+      let cos x = smul 0.5 (add (exp(iscale 1.0 x)) (exp(iscale -1.0 x)))
+      // sin(x) = (exp(i.x) - exp(-i.x))/2 . (-i) 
+      let sin x = smul 0.5 (sub (exp(iscale 1.0 x)) (exp(iscale -1.0 x))) |> iscale (-1.0)
+      // tan(x) = (exp(i.x) - exp(-i.x)) . (-i) / (exp(i.x) + exp(-i.x)) 
+      //        = (exp(2i.x) - 1.0)      . (-i) / (exp(2i.x) + 1.0)      
+      let tan x = let exp2ix = exp(iscale 2.0 x) in
+                  (div (sub exp2ix one) (add exp2ix one)) |> iscale -1.0
+
+
+    type Complex with 
+        static member Create(a,b) = Complex.mkRect (a,b)
+        static member CreatePolar(a,b) = Complex.mkPolar (a,b)
+        member x.Magnitude = Complex.magnitude x
+        member x.Phase = Complex.phase x
+        member x.RealPart = x.r
+        member x.ImaginaryPart = x.i
+        member x.Conjugate = Complex.conjugate x
+
+        static member Sin(x) = Complex.sin(x)
+        static member Cos(x) = Complex.cos(x)
+        static member Abs(x) = Complex.abs(x)
+        static member Tan(x) = Complex.tan(x)
+        static member Log(x) = Complex.log(x)
+        static member Exp(x) = Complex.exp(x)
+        static member Sqrt(x) = Complex.sqrt(x)
+        
+        static member Zero = Complex.zero
+        static member One = Complex.one 
+        static member OneI = Complex.onei 
+        static member ( +  ) (a,b) = Complex.add a b
+        static member ( -  ) (a,b) = Complex.sub a b
+        static member ( *  ) (a,b) = Complex.mul a b
+        static member ( /  ) (a,b) = Complex.div a b
+        static member ( ~- ) a = Complex.neg a
+        static member ( * ) (a,b) = Complex.smul a b
+        static member ( * ) (a,b) = Complex.muls a b
+
+
+    module ComplexTopLevelOperators = 
+        let complex x y = Complex.mkRect (x,y)
+
--- fsharp-3.1.1.26+dfsg2.orig/FSharp.PowerPack/math/complex.fsi
+++ fsharp-3.1.1.26+dfsg2/FSharp.PowerPack/math/complex.fsi
@@ -1,136 +1,136 @@
-// (c) Microsoft Corporation 2005-2009. 
-
-namespace Microsoft.FSharp.Math
-
-    open System
-      
-    /// The type of complex numbers stored as pairs of 64-bit floating point numbers in rectangular coordinates
-    [<Struct>]
-    [<CustomEquality; CustomComparison>]
-    type Complex = 
-        /// The real part of a complex number
-        member r: float
-        /// The imaginary part of a complex number
-        member i: float
-        /// The polar-coordinate magnitude of a complex number
-        member Magnitude: float
-        /// The polar-coordinate phase of a complex number
-        member Phase: float
-        /// The real part of a complex number
-        member RealPart: float
-        /// The imaginary part of a complex number
-        member ImaginaryPart: float
-        /// The conjugate of a complex number, i.e. x-yi
-        member Conjugate: Complex
-        /// Create a complex number x+ij using rectangular coordinates
-        static member Create      : float * float -> Complex
-        /// Create a complex number using magnitude/phase polar coordinates
-        static member CreatePolar : float * float -> Complex
-        /// The complex number 0+0i
-        static member Zero   : Complex
-        /// The complex number 1+0i
-        static member One    : Complex
-        /// The complex number 0+1i
-        static member OneI   : Complex
-        /// Add two complex numbers
-        static member ( +  ) : Complex * Complex -> Complex
-        /// Subtract one complex number from another
-        static member ( -  ) : Complex * Complex -> Complex
-        /// Multiply two complex numbers
-        static member ( *  ) : Complex * Complex -> Complex
-        /// Complex division of two complex numbers
-        static member ( /  ) : Complex * Complex -> Complex
-        /// Unary negation of a complex number
-        static member ( ~- ) : Complex           -> Complex
-        /// Multiply a scalar by a complex number 
-        static member ( * ) : float   * Complex -> Complex
-        /// Multiply a complex number by a scalar
-        static member ( * ) : Complex * float   -> Complex
-
-        static member Sin : Complex -> Complex
-        static member Cos : Complex -> Complex
-        
-        /// Computes the absolute value of a complex number: e.g. Abs x+iy = sqrt(x**2.0 + y**2.0.)
-        /// Note: Complex.Abs(z) is the same as z.Magnitude
-        static member Abs : Complex -> float
-        static member Tan : Complex -> Complex
-        static member Log : Complex -> Complex
-        static member Exp : Complex -> Complex
-        static member Sqrt : Complex -> Complex
-        
-        override ToString : unit -> string
-        override Equals : obj -> bool
-        interface System.IComparable
-        member ToString : format:string -> string
-        member ToString : format:string * provider:System.IFormatProvider -> string
-
-    /// The type of complex numbers 
-    type complex = Complex
-
-
-    [<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
-    [<RequireQualifiedAccess>]
-    module Complex =
-
-        val mkRect: float * float -> complex
-
-          /// The polar-coordinate magnitude of a complex number
-        val magnitude: complex -> float
-          /// The polar-coordinate phase of a complex number
-        val phase     : complex -> float
-          /// The real part of a complex number
-        val realPart  : complex -> float
-          /// The imaginary part of a complex number
-        val imagPart  : complex -> float
-          /// Create a complex number using magnitude/phase polar coordinates
-        val mkPolar : float * float -> complex
-        /// A complex of magnitude 1 and the given phase and , i.e. cis x = mkPolar 1.0 x
-        val cis     : float -> complex
-        
-          /// The conjugate of a complex number, i.e. x-yi
-        val conjugate : complex -> complex
-
-          /// The complex number 0+0i
-        val zero    : complex
-          /// The complex number 1+0i
-        val one     : complex
-          /// The complex number 0+1i
-        val onei    : complex
-          /// Add two complex numbers
-        val add     : complex -> complex -> complex
-          /// Subtract one complex number from another
-        val sub     : complex -> complex -> complex
-          /// Multiply two complex numbers
-        val mul     : complex -> complex -> complex
-          /// Complex division of two complex numbers
-        val div     : complex -> complex -> complex
-          /// Unary negation of a complex number
-        val neg     : complex -> complex
-          /// Multiply a scalar by a complex number 
-        val smul    : float -> complex -> complex
-          /// Multiply a complex number by a scalar
-        val muls    : complex -> float -> complex
-
-          /// pi
-        val pi  : Complex
-          /// exp(x) = e^x
-        val exp : Complex -> Complex
-          /// log(x) is natural log (base e)
-        val log : Complex -> Complex
-          /// sqrt(x) and 0 <= phase(x) < pi
-        val sqrt : Complex -> Complex
-          /// Sine
-        val sin : Complex -> Complex    
-          /// Cosine
-        val cos : Complex -> Complex
-          /// Tagent
-        val tan : Complex -> Complex
-        
-
-    [<AutoOpen>]
-    module ComplexTopLevelOperators = 
-        /// Constructs a complex number from both the real and imaginary part.
-        val complex : float -> float -> complex
-
-
-
+// (c) Microsoft Corporation 2005-2009. 
+
+namespace Microsoft.FSharp.Math
+
+    open System
+      
+    /// The type of complex numbers stored as pairs of 64-bit floating point numbers in rectangular coordinates
+    [<Struct>]
+    [<CustomEquality; CustomComparison>]
+    type Complex = 
+        /// The real part of a complex number
+        member r: float
+        /// The imaginary part of a complex number
+        member i: float
+        /// The polar-coordinate magnitude of a complex number
+        member Magnitude: float
+        /// The polar-coordinate phase of a complex number
+        member Phase: float
+        /// The real part of a complex number
+        member RealPart: float
+        /// The imaginary part of a complex number
+        member ImaginaryPart: float
+        /// The conjugate of a complex number, i.e. x-yi
+        member Conjugate: Complex
+        /// Create a complex number x+ij using rectangular coordinates
+        static member Create      : float * float -> Complex
+        /// Create a complex number using magnitude/phase polar coordinates
+        static member CreatePolar : float * float -> Complex
+        /// The complex number 0+0i
+        static member Zero   : Complex
+        /// The complex number 1+0i
+        static member One    : Complex
+        /// The complex number 0+1i
+        static member OneI   : Complex
+        /// Add two complex numbers
+        static member ( +  ) : Complex * Complex -> Complex
+        /// Subtract one complex number from another
+        static member ( -  ) : Complex * Complex -> Complex
+        /// Multiply two complex numbers
+        static member ( *  ) : Complex * Complex -> Complex
+        /// Complex division of two complex numbers
+        static member ( /  ) : Complex * Complex -> Complex
+        /// Unary negation of a complex number
+        static member ( ~- ) : Complex           -> Complex
+        /// Multiply a scalar by a complex number 
+        static member ( * ) : float   * Complex -> Complex
+        /// Multiply a complex number by a scalar
+        static member ( * ) : Complex * float   -> Complex
+
+        static member Sin : Complex -> Complex
+        static member Cos : Complex -> Complex
+        
+        /// Computes the absolute value of a complex number: e.g. Abs x+iy = sqrt(x**2.0 + y**2.0.)
+        /// Note: Complex.Abs(z) is the same as z.Magnitude
+        static member Abs : Complex -> float
+        static member Tan : Complex -> Complex
+        static member Log : Complex -> Complex
+        static member Exp : Complex -> Complex
+        static member Sqrt : Complex -> Complex
+        
+        override ToString : unit -> string
+        override Equals : obj -> bool
+        interface System.IComparable
+        member ToString : format:string -> string
+        member ToString : format:string * provider:System.IFormatProvider -> string
+
+    /// The type of complex numbers 
+    type complex = Complex
+
+
+    [<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+    [<RequireQualifiedAccess>]
+    module Complex =
+
+        val mkRect: float * float -> complex
+
+          /// The polar-coordinate magnitude of a complex number
+        val magnitude: complex -> float
+          /// The polar-coordinate phase of a complex number
+        val phase     : complex -> float
+          /// The real part of a complex number
+        val realPart  : complex -> float
+          /// The imaginary part of a complex number
+        val imagPart  : complex -> float
+          /// Create a complex number using magnitude/phase polar coordinates
+        val mkPolar : float * float -> complex
+        /// A complex of magnitude 1 and the given phase and , i.e. cis x = mkPolar 1.0 x
+        val cis     : float -> complex
+        
+          /// The conjugate of a complex number, i.e. x-yi
+        val conjugate : complex -> complex
+
+          /// The complex number 0+0i
+        val zero    : complex
+          /// The complex number 1+0i
+        val one     : complex
+          /// The complex number 0+1i
+        val onei    : complex
+          /// Add two complex numbers
+        val add     : complex -> complex -> complex
+          /// Subtract one complex number from another
+        val sub     : complex -> complex -> complex
+          /// Multiply two complex numbers
+        val mul     : complex -> complex -> complex
+          /// Complex division of two complex numbers
+        val div     : complex -> complex -> complex
+          /// Unary negation of a complex number
+        val neg     : complex -> complex
+          /// Multiply a scalar by a complex number 
+        val smul    : float -> complex -> complex
+          /// Multiply a complex number by a scalar
+        val muls    : complex -> float -> complex
+
+          /// pi
+        val pi  : Complex
+          /// exp(x) = e^x
+        val exp : Complex -> Complex
+          /// log(x) is natural log (base e)
+        val log : Complex -> Complex
+          /// sqrt(x) and 0 <= phase(x) < pi
+        val sqrt : Complex -> Complex
+          /// Sine
+        val sin : Complex -> Complex    
+          /// Cosine
+        val cos : Complex -> Complex
+          /// Tagent
+        val tan : Complex -> Complex
+        
+
+    [<AutoOpen>]
+    module ComplexTopLevelOperators = 
+        /// Constructs a complex number from both the real and imaginary part.
+        val complex : float -> float -> complex
+
+
+
--- fsharp-3.1.1.26+dfsg2.orig/FSharp.PowerPack/math/matrix.fs
+++ fsharp-3.1.1.26+dfsg2/FSharp.PowerPack/math/matrix.fs
@@ -1,2563 +1,2563 @@
-// (c) Microsoft Corporation 2005-2009. 
-
-//----------------------------------------------------------------------------
-// An implementation of generic dense and sparse matrix types.
-//
-// Overview and suffix documentation
-//    _GU  = generic unspecialized (Matrix<T>, Vector<T> etc.) 
-//    _GUA = generic unspecialized op on (underlying) array
-//    _DS  = Double specialized (Matrix<float> = matrix, Vector<float> = vector etc.)
-//
-//    DM   = dense matrix
-//    SM   = sparse matrix
-//    V    = vector (dense)
-//    RV   = row vector (dense)
-
-
-namespace Microsoft.FSharp.Math
-
-    #nowarn "60" // implementations in augmentations
-    #nowarn "69" // implementations in augmentations
-
-    open Microsoft.FSharp.Math
-    open System
-    open System.Globalization
-    open System.Collections
-    open System.Collections.Generic
-    open System.Diagnostics
-    type permutation = int -> int
-
-
-//=========================================================================
-// (c) Microsoft Corporation 2005-2009. 
-//=========================================================================
-
-    [<AutoOpen>]
-    module Helpers = 
-        let sparseNYI() = failwith "this operation is not supported on sparse matrices"
-        let sparseNotMutable() = failwith "sparse matrices are not mutable"
-        
-        [<RequiresExplicitTypeArguments>]
-        let opsdata<'T> = GlobalAssociations.TryGetNumericAssociation<'T>()
-        
-        [<Literal>]
-        let DenseMaxDisplay = 50
-        [<Literal>]
-        let VectorMaxDisplay = 100
-    
-    
-    /// The value stored for the dictionary of numeric operations. If none is present then this indicates
-    /// no operations are known for this type.
-    type OpsData<'T> = INumeric<'T> option
-
-    type DenseMatrix<'T>(opsData : OpsData<'T>, values : 'T[,]) = 
-        member m.OpsData =  opsData
-        member m.Values =  values
-        member m.NumRows = values.GetLength(0)
-        member m.NumCols = values.GetLength(1)
-
-        member m.ElementOps = 
-            match opsData with 
-            | None -> raise (new System.NotSupportedException("The element type carried by this matrix does not support numeric operations"))
-            | Some a -> a
-
-        member m.Item
-           with get (i,j) = values.[i,j]
-           and  set (i,j) x = values.[i,j] <- x
-
-
-
-    type SparseMatrix<'T>(opsData : OpsData<'T>, sparseValues : 'T array, sparseRowOffsets : int array, ncols:int, columnValues: int array) = 
-        member m.OpsData = opsData; 
-        member m.NumCols = ncols
-        member m.NumRows = sparseRowOffsets.Length - 1
-        member m.SparseColumnValues = columnValues
-        member m.SparseRowOffsets =  sparseRowOffsets (* nrows + 1 elements *)
-        member m.SparseValues =  sparseValues
-
-        member m.ElementOps = 
-              match opsData with 
-              | None -> raise (new System.NotSupportedException("The element type carried by this matrix does not support numeric operations"))
-              | Some a -> a
-
-        member m.MinIndexForRow i = m.SparseRowOffsets.[i]
-        member m.MaxIndexForRow i = m.SparseRowOffsets.[i+1]
-              
-
-        member m.Item 
-            with get (i,j) = 
-                let imax = m.NumRows
-                let jmax = m.NumCols
-                if j < 0 || j >= jmax || i < 0 || i >= imax then raise (new System.ArgumentOutOfRangeException()) else
-                let kmin = m.MinIndexForRow i
-                let kmax = m.MaxIndexForRow i
-                let rec loopRow k =
-                    (* note: could do a binary chop here *)
-                    if k >= kmax then m.ElementOps.Zero else
-                    let j2 = columnValues.[k]
-                    if j < j2 then m.ElementOps.Zero else
-                    if j = j2 then sparseValues.[k] else 
-                    loopRow (k+1)
-                loopRow kmin
-
-#if FX_NO_DEBUG_DISPLAYS
-#else
-    [<System.Diagnostics.DebuggerDisplay("{DebugDisplay}")>]
-#endif
-    [<StructuredFormatDisplay("matrix {StructuredDisplayAsArray}")>]
-    [<CustomEquality; CustomComparison>]
-    //[<System.Diagnostics.DebuggerTypeProxy(typedefof<MatrixDebugView<_>>)>]
-    type Matrix<'T> = 
-        | DenseRepr of DenseMatrix<'T>
-        | SparseRepr of SparseMatrix<'T>
-        interface System.IComparable
-        interface IStructuralComparable
-        interface IStructuralEquatable
-        interface IEnumerable<'T> 
-        interface IEnumerable
-
-        member m.ElementOps = match m with DenseRepr mr -> mr.ElementOps | SparseRepr mr -> mr.ElementOps
-        member m.NumRows    = match m with DenseRepr mr -> mr.NumRows    | SparseRepr mr ->  mr.NumRows
-        member m.NumCols    = match m with DenseRepr mr -> mr.NumCols    | SparseRepr mr ->  mr.NumCols
-
-        member m.Item 
-            with get (i,j) = 
-                match m with 
-                | DenseRepr dm -> dm.[i,j]
-                | SparseRepr sm -> sm.[i,j]
-            and set (i,j) x = 
-              match m with 
-              | DenseRepr dm -> dm.[i,j] <- x
-              | SparseRepr _ -> sparseNotMutable()
-
-
-#if FX_NO_DEBUG_DISPLAYS
-#else
-        [<DebuggerBrowsable(DebuggerBrowsableState.Collapsed)>]
-#endif
-        member m.IsDense = match m with DenseRepr _ -> true | SparseRepr _ -> false
-
-#if FX_NO_DEBUG_DISPLAYS
-#else
-        [<DebuggerBrowsable(DebuggerBrowsableState.Collapsed)>]
-#endif
-        member m.IsSparse = match m with DenseRepr _ -> false | SparseRepr _ -> true
-
-#if FX_NO_DEBUG_DISPLAYS
-#else
-        [<DebuggerBrowsable(DebuggerBrowsableState.Collapsed)>]
-#endif
-        member m.InternalSparseColumnValues = match m with DenseRepr _ -> invalidOp "not a sparse matrix" | SparseRepr mr -> mr.SparseColumnValues
-
-#if FX_NO_DEBUG_DISPLAYS
-#else
-        [<DebuggerBrowsable(DebuggerBrowsableState.Collapsed)>]
-#endif
-        member m.InternalSparseRowOffsets = match m with DenseRepr _ -> invalidOp "not a sparse matrix" | SparseRepr mr -> mr.SparseRowOffsets
-
-#if FX_NO_DEBUG_DISPLAYS
-#else
-        [<DebuggerBrowsable(DebuggerBrowsableState.Collapsed)>]
-#endif
-        member m.InternalSparseValues = match m with DenseRepr _ -> invalidOp "not a sparse matrix" | SparseRepr mr -> mr.SparseValues
-
-#if FX_NO_DEBUG_DISPLAYS
-#else
-        [<DebuggerBrowsable(DebuggerBrowsableState.Collapsed)>]
-#endif
-        member m.InternalDenseValues = match m with DenseRepr mr -> mr.Values | SparseRepr _ -> invalidOp "not a dense matrix"
-
-#if FX_NO_DEBUG_DISPLAYS
-#else
-    [<System.Diagnostics.DebuggerDisplay("{DebugDisplay}")>]
-#endif
-#if FX_NO_DEBUG_PROXIES
-#else
-    [<System.Diagnostics.DebuggerTypeProxy(typedefof<RowVectorDebugView<_>>)>]
-#endif
-    [<StructuredFormatDisplay("rowvec {StructuredDisplayAsArray}")>]
-    [<Sealed>]
-    type RowVector<'T>(opsRV : INumeric<'T> option, arrRV : 'T array ) =
-        interface System.IComparable
-        interface IStructuralComparable
-        interface IStructuralEquatable 
-
-
-#if FX_NO_DEBUG_DISPLAYS
-#else
-        [<DebuggerBrowsable(DebuggerBrowsableState.Collapsed)>]
-#endif
-        member x.InternalValues = arrRV
-        member x.Values = arrRV
-        member x.OpsData = opsRV
-        
-        
-        interface IEnumerable<'T> with 
-            member x.GetEnumerator() = (arrRV :> seq<_>).GetEnumerator()
-        interface IEnumerable  with 
-            member x.GetEnumerator() = (arrRV :> IEnumerable).GetEnumerator()
-
-        member x.Length = arrRV.Length
-        member x.NumCols = arrRV.Length
-        member x.ElementOps = 
-            match opsRV with 
-            | None -> raise (new System.NotSupportedException("The element type carried by this row vector does not support numeric operations"))
-            | Some a -> a
-
-        member v.Item
-           with get i = arrRV.[i]
-           and  set i x = arrRV.[i] <- x
-
-    and 
-        [<Sealed>]
-        RowVectorDebugView<'T>(v: RowVector<'T>)  =  
-
-#if FX_NO_DEBUG_DISPLAYS
-#else
-             [<System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.RootHidden)>]
-#endif
-             member x.Items = v |> Seq.truncate 1000 |> Seq.toArray 
-
-#if FX_NO_DEBUG_DISPLAYS
-#else
-    [<System.Diagnostics.DebuggerDisplay("{DebugDisplay}")>]
-#endif
-#if FX_NO_DEBUG_PROXIES
-#else
-    [<System.Diagnostics.DebuggerTypeProxy(typedefof<VectorDebugView<_>>)>]
-#endif
-    [<StructuredFormatDisplay("vector {StructuredDisplayAsArray}")>]
-    [<Sealed>]
-    type Vector<'T>(opsV : INumeric<'T> option, arrV : 'T array) =
-
-#if FX_NO_DEBUG_DISPLAYS
-#else
-        [<DebuggerBrowsable(DebuggerBrowsableState.Collapsed)>]
-#endif
-        member x.InternalValues = arrV
-        member x.Values = arrV
-        member x.OpsData = opsV
-        interface System.IComparable
-        interface IStructuralComparable
-        interface IStructuralEquatable 
-
-        interface IEnumerable<'T> with 
-            member x.GetEnumerator() = (arrV :> seq<_>).GetEnumerator()
-        interface IEnumerable  with 
-            member x.GetEnumerator() = (arrV :> IEnumerable).GetEnumerator()
-        
-
-        member m.Length = arrV.Length
-        member m.NumRows = arrV.Length
-        member m.ElementOps = 
-            match opsV with 
-            | None -> raise (new System.NotSupportedException("The element type carried by this vector does not support numeric operations"))
-            | Some a -> a
-        member v.Item
-           with get i = arrV.[i]
-           and  set i x = arrV.[i] <- x
-
-#if FX_NO_DEBUG_PROXIES
-#else
-    and 
-        [<Sealed>]
-        VectorDebugView<'T>(v: Vector<'T>)  =  
-
-             [<System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.RootHidden)>]
-             member x.Items = v |> Seq.truncate 1000 |> Seq.toArray 
-#endif
-
-
-    /// Implementations of operations that will work for any type
-    module GenericImpl = 
-
-        type OpsData<'T> = INumeric<'T> option
-
-        let opsOfOpsData (d : OpsData<'T>)  =
-             match d with 
-             | None -> raise (new System.NotSupportedException("The element type '"+(typeof<'T>).ToString()+"' carried by this vector or matrix does not support numeric operations (i.e. does not have a registered numeric association)"))
-             | Some a -> a
-
-        let getNormOps (ops:INumeric<'T>) = 
-            match box ops with
-              | :? INormFloat<'T> as ops -> ops
-              | _ -> raise (new System.NotSupportedException("The element type '"+(typeof<'T>.ToString())+"' carried by this vector or matrix does not support the INormFloat<_> operation (i.e. does not have a registered numeric association that supports this type)"))
-
-        let mkDenseMatrixGU ops arr = DenseMatrix(ops,arr)
-        let mkRowVecGU ops arr = RowVector(ops, arr)
-        let mkVecGU ops arr = Vector(ops,arr)
-
-        let inline getArray2D  (arrDM : _[,]) i j   = arrDM.[i,j]
-        let inline setArray2D  (arrDM  : _[,]) i j x = arrDM.[i,j] <- x
-
-        let inline createArray m = Array.zeroCreate m
-
-        let inline createArray2D m n = Array2D.zeroCreate m n
-
-        let inline assignArray2D m n f arr =  
-            for i = 0 to m - 1 do 
-                for j = 0 to n - 1 do 
-                    (arr  : _[,]).[i,j] <- f i j
-
-        let inline assignConstArray2D m n x arr =  
-            for i = 0 to m - 1 do 
-                for j = 0 to n - 1 do 
-                    (arr  : _[,]).[i,j] <- x
-
-        let inline assignDenseMatrixGU f (a:DenseMatrix<_>) = 
-            assignArray2D a.NumRows a.NumCols f a.Values
-        
-        let inline assignArray m f (arr : _[]) = 
-            for i = 0 to m - 1 do 
-                arr.[i] <- f i
-
-        let inline assignConstArray m x (arr : _[]) = 
-            for i = 0 to m - 1 do 
-                arr.[i] <- x
-
-        let inline assignVecGU f (a:Vector<_>) = 
-            assignArray a.NumRows f a.Values
-        
-        let inline assignRowVecGU f (a:RowVector<_>) = 
-            assignArray a.NumCols f a.Values
-        
-        let createConstDenseMatrixGU ops m n x = 
-            let arr = createArray2D m n 
-            assignConstArray2D m n x arr;
-            DenseMatrix(ops,arr)
-        
-        let createConstRowVecGU ops m x = 
-            let arr = createArray m 
-            assignConstArray m x arr;
-            mkRowVecGU ops arr
-        
-        let createConstVecGU ops m x = 
-            let arr = createArray m 
-            assignConstArray m x arr;
-            mkVecGU ops arr
-
-
-        let inline createDenseMatrixGU ops m n f = (* inline eliminates unknown f call *)
-            let arr = createArray2D m n 
-            assignArray2D m n f arr;
-            DenseMatrix(ops,arr)
-        
-        let createRowVecGU ops m f = 
-            let arr = createArray m 
-            assignArray m f arr;
-            mkRowVecGU ops arr
-        
-        let inline createVecGU ops m f = (* inline eliminates unknown f call *)
-            let arr = createArray m 
-            assignArray m f arr;
-            mkVecGU ops arr
-
-        /// Create a matrix from a sparse sequence 
-        let initSparseMatrixGU maxi maxj ops s = 
-
-            (* nb. could use sorted dictionary but that is in System.dll *)
-            let tab = Array.create maxi null
-            let count = ref 0
-            for (i,j,v) in s do
-                if i < 0 || i >= maxi || j <0 || j >= maxj then failwith "initial value out of range";
-                count := !count + 1;
-                let tab2 = 
-                    match tab.[i] with 
-                    | null -> 
-                        let tab2 = new Dictionary<_,_>(3) 
-                        tab.[i] <- tab2;
-                        tab2
-                    | tab2 -> tab2
-                tab2.[j] <- v
-            // optimize this line....
-            let offsA =  
-               let rowsAcc = Array.zeroCreate (maxi + 1)
-               let mutable acc = 0 
-               for i = 0 to maxi-1 do 
-                  rowsAcc.[i] <- acc;
-                  acc <- match tab.[i] with 
-                          | null -> acc
-                          | tab2 -> acc+tab2.Count
-               rowsAcc.[maxi] <- acc;
-               rowsAcc
-               
-            let colsA,valsA = 
-               let colsAcc = new ResizeArray<_>(!count)
-               let valsAcc = new ResizeArray<_>(!count)
-               for i = 0 to maxi-1 do 
-                  match tab.[i] with 
-                  | null -> ()
-                  | tab2 -> tab2 |> Seq.toArray |> Array.sortBy (fun kvp -> kvp.Key) |> Array.iter (fun kvp -> colsAcc.Add(kvp.Key); valsAcc.Add(kvp.Value));
-               colsAcc.ToArray(), valsAcc.ToArray()
-
-            SparseMatrix(opsData=ops, sparseValues=valsA, sparseRowOffsets=offsA, ncols=maxj, columnValues=colsA)
-        
-        let zeroizeDenseMatrixGUA arr  m n : DenseMatrix<'T> = 
-            let opsData = opsdata<'T> 
-            let ops = opsOfOpsData opsData 
-            let zero = ops.Zero 
-            assignArray2D m n (fun _ _ -> zero) arr;
-            DenseMatrix(opsData,arr)
-
-        let zeroizeArray opsData arr m  = 
-            let ops = opsOfOpsData opsData 
-            let zero = ops.Zero 
-            assignArray m (fun _ -> zero) arr
-
-        let zeroizeVecGUA arr m  : Vector<'T> = 
-            let opsData = opsdata<'T> 
-            zeroizeArray opsData arr m;
-            mkVecGU opsData arr
-
-        let zeroizeRowVecGUA arr m  : RowVector<'T> = 
-            let opsData = opsdata<'T> 
-            zeroizeArray opsData arr m;
-            mkRowVecGU opsData arr
-
-        let listDenseMatrixGU ops xss =
-            let m = List.length xss
-            match xss with 
-            | [] -> invalidArg "xss" "unexpected empty list"
-            | h :: t -> 
-              let n = List.length h
-              if not (List.forall (fun xs -> List.length xs=n) t) then invalidArg "xss" "the lists are not all of the same length";
-              let values = Array2D.zeroCreate m n
-              List.iteri (fun i rw -> List.iteri (fun j x -> values.[i,j] <- x) rw) xss;
-              DenseMatrix(ops,values)
-        
-        let listRowVecGU ops xs = mkRowVecGU ops (Array.ofList xs) 
-        let listVecGU ops xs = mkVecGU ops (Array.ofList xs) 
-
-        let seqDenseMatrixGU ops xss = listDenseMatrixGU ops (xss |> Seq.toList |> List.map Seq.toList)
-        let seqVecGU  ops xss = listVecGU ops (xss |> Seq.toList)
-        let seqRowVecGU ops xss = listRowVecGU ops (xss |> Seq.toList)
-
-        let inline binaryOpDenseMatrixGU f (a:DenseMatrix<_>) (b:DenseMatrix<_>) = (* pointwise binary operator *)
-            let nA = a.NumCols
-            let mA = a.NumRows
-            let nB = b.NumCols 
-            let mB = b.NumRows
-            if nA<>nB || mA<>mB then invalidArg "a" "the two matrices do not have compatible dimensions";
-            let arrA = a.Values 
-            let arrB = b.Values 
-            createDenseMatrixGU a.OpsData mA nA (fun i j -> f (getArray2D arrA i j) (getArray2D arrB i j))
-
-
-        let nonZeroEntriesSparseMatrixGU  (a:SparseMatrix<_>) = 
-            // This is heavily used, and this version is much faster than
-            // the sequence operators.
-            let entries = new ResizeArray<_>(a.SparseColumnValues.Length)
-            let imax = a.NumRows
-            let ops = a.ElementOps 
-            let zero = ops.Zero
-            for i in 0 .. imax - 1 do
-              let kmin = a.MinIndexForRow i
-              let kmax = a.MaxIndexForRow i
-              for k in kmin .. kmax - 1 do
-                  let j = a.SparseColumnValues.[k]
-                  let v = a.SparseValues.[k]
-                  if not (ops.Equals(v,zero)) then
-                    entries.Add((i,j,v))
-            (entries :> seq<_>)
-
-        let nonzeroEntriesDenseMatrixGU  (a:DenseMatrix<_>) = 
-            let imax = a.NumRows
-            let jmax = a.NumCols
-            let ops = a.ElementOps 
-            let zero = ops.Zero
-            seq { for i in 0 .. imax - 1 do 
-                    for j in 0 .. jmax - 1 do 
-                        let v = a.[i,j] 
-                        if not (ops.Equals(v, zero)) then
-                             yield (i,j,v) }
-
-
-        // pointwise operation on two sparse matrices. f must be zero-zero-preserving, i.e. (f 0 0 = 0) 
-        let binaryOpSparseMatrixGU f (a:SparseMatrix<_>) (b:SparseMatrix<_>) = 
-            let ops = a.ElementOps 
-            let zero = ops.Zero
-            let imax1 = a.NumRows  
-            let imax2 = b.NumRows
-            let jmax1 = a.NumCols
-            let jmax2 = b.NumCols
-            if imax1 <> imax2 || jmax1 <> jmax2 then invalidArg "b" "the two matrices do not have compatible dimensions";
-            let imin = 0
-            let imax = imax1
-            let jmax = jmax1
-            let rowsR = Array.zeroCreate (imax+1)
-            let colsR = new ResizeArray<_>(max a.SparseColumnValues.Length b.SparseColumnValues.Length)
-            let valsR = new ResizeArray<_>(max a.SparseValues.Length b.SparseValues.Length)
-            let rec loopRows i  = 
-                rowsR.[i] <- valsR.Count;            
-                if i >= imax1 then () else
-                let kmin1 = a.MinIndexForRow i
-                let kmax1 = a.MaxIndexForRow i 
-                let kmin2 = b.MinIndexForRow i
-                let kmax2 = b.MaxIndexForRow i
-                let rec loopRow k1 k2  =
-                    if k1 >= kmax1 && k2 >= kmax2 then () else
-                    let j1 = if k1 >= kmax1 then jmax else a.SparseColumnValues.[k1]
-                    let j2 = if k2 >= kmax2 then jmax else b.SparseColumnValues.[k2]
-                    let v1 = if j1 <= j2 then a.SparseValues.[k1] else zero
-                    let v2 = if j2 <= j1 then b.SparseValues.[k2] else zero
-                    let jR = min j1 j2
-                    let vR = f v1 v2
-                    (* if vR <> zero then  *)
-                    colsR.Add(jR);
-                    valsR.Add(vR);
-                    loopRow (if j1 <= j2 then k1+1 else k1) (if j2 <= j1 then k2+1 else k2)
-                loopRow kmin1 kmin2;
-                loopRows (i+1) 
-            loopRows imin;
-            SparseMatrix(opsData= a.OpsData, 
-                         sparseRowOffsets=rowsR, 
-                         ncols= a.NumCols, 
-                         columnValues=colsR.ToArray(), 
-                         sparseValues=valsR.ToArray())
-
-        let inline binaryOpRowVecGU f (a:RowVector<_>) (b:RowVector<_>) = (* pointwise binary operator *)
-            let mA = a.NumCols
-            let mB = b.NumCols
-            if mA<>mB then invalidArg "b" "the two vectors do not have compatible dimensions"
-            createRowVecGU a.OpsData mA (fun i -> f a.[i] b.[i])
-
-        let inline binaryOpVecGU f (a:Vector<_>) (b:Vector<_>) = (* pointwise binary operator *)
-            let mA = a.NumRows
-            let mB = b.NumRows
-            if mA<>mB then invalidArg "b" "the two vectors do not have compatible dimensions"
-            createVecGU a.OpsData mA (fun i -> f a.[i] b.[i])
-
-        let inline unaryOpDenseMatrixGU f (a:DenseMatrix<_>) =
-            let nA = a.NumCols 
-            let mA = a.NumRows 
-            let arrA = a.Values 
-            createDenseMatrixGU a.OpsData mA nA (fun i j -> f (getArray2D arrA i j))
-
-        let inline unaryOpRowVecGU f (a:RowVector<_>) =
-            let mA = a.NumCols
-            let arrA = a.Values 
-            createRowVecGU a.OpsData mA (fun j -> f arrA.[j])
-
-        let inline unaryOpVectorGU f (a:Vector<_>) =
-            let mA = a.NumRows 
-            let arrA = a.Values 
-            createVecGU a.OpsData mA (fun i -> f arrA.[i])
-
-        let unaryOpSparseGU f (a:SparseMatrix<_>) = (* pointwise zero-zero-preserving binary operator (f 0 = 0) *)
-            SparseMatrix(opsData=a.OpsData,
-                         sparseRowOffsets=Array.copy a.SparseRowOffsets, 
-                         columnValues=Array.copy a.SparseColumnValues, 
-                         sparseValues=Array.map f a.SparseValues, 
-                         ncols=a.NumCols)
-
-        // Strictly speaking, sparse arrays are non mutable so no copy is ever needed. But implementing it *)
-        // anyway in case we move to mutability *)
-        let copySparseGU (a:SparseMatrix<_>) = 
-            SparseMatrix(opsData=a.OpsData,
-                         sparseRowOffsets=Array.copy a.SparseRowOffsets, 
-                         columnValues=Array.copy a.SparseColumnValues,
-                         sparseValues=Array.copy a.SparseValues, 
-                         ncols=a.NumCols)
-
-        let addDenseMatrixGU  (a:DenseMatrix<_>)  b = let ops = a.ElementOps in binaryOpDenseMatrixGU (fun x y -> ops.Add(x, y)) a b
-        let addSparseMatrixGU (a:SparseMatrix<_>) b = let ops = a.ElementOps in binaryOpSparseMatrixGU (fun x y -> ops.Add(x, y)) a b
-        let addRowVecGU       (a:RowVector<_>)    b = let ops = a.ElementOps in binaryOpRowVecGU (fun x y -> ops.Add(x, y)) a b
-        let addVecGU          (a:Vector<_>)       b = let ops = a.ElementOps in binaryOpVecGU  (fun x y -> ops.Add(x, y)) a b 
-
-        let subDenseMatrixGU  (a:DenseMatrix<_>)  b = let ops = a.ElementOps in binaryOpDenseMatrixGU (fun x y -> ops.Subtract(x, y)) a b
-        let subSparseMatrixGU (a:SparseMatrix<_>) b = let ops = a.ElementOps in binaryOpSparseMatrixGU (fun x y -> ops.Subtract(x, y)) a b
-        let subRowVecGU       (a:RowVector<_>)    b = let ops = a.ElementOps in binaryOpRowVecGU (fun x y -> ops.Subtract(x, y)) a b
-        let subVecGU          (a:Vector<_>)       b = let ops = a.ElementOps in binaryOpVecGU  (fun x y -> ops.Subtract(x, y)) a b 
-
-        ///Point-wise multiplication 
-        let cptMulDenseMatrixGU  (a:DenseMatrix<_>)  b = let ops = a.ElementOps in binaryOpDenseMatrixGU  (fun x y -> ops.Multiply(x, y)) a b
-        let cptMulSparseMatrixGU (a:SparseMatrix<_>) b = let ops = a.ElementOps in binaryOpSparseMatrixGU  (fun x y -> ops.Multiply(x, y)) a b
-        let cptMulRowVecGU       (a:RowVector<_>)    b = let ops = a.ElementOps in binaryOpRowVecGU (fun x y -> ops.Multiply(x, y)) a b
-        let cptMulVecGU          (a:Vector<_>)       b = let ops = a.ElementOps in binaryOpVecGU  (fun x y -> ops.Multiply(x, y)) a b
-
-        let cptMaxDenseMatrixGU  (a:DenseMatrix<_>) b = binaryOpDenseMatrixGU  max a b
-        let cptMinDenseMatrixGU  (a:DenseMatrix<_>) b = binaryOpDenseMatrixGU  min a b
-        let cptMaxSparseMatrixGU (a:SparseMatrix<_>) b = binaryOpSparseMatrixGU  max a b
-        let cptMinSparseMatrixGU (a:SparseMatrix<_>) b = binaryOpSparseMatrixGU  min a b
-
-        let cptMaxVecGU (a:Vector<_>) b = binaryOpVecGU max a b
-        let cptMinVecGU (a:Vector<_>) b = binaryOpVecGU min a b
-
-        let add (ops : INumeric<'T>) x y = ops.Add(x,y) 
-        let sub (ops : INumeric<'T>) x y = ops.Subtract(x,y) 
-        let mul (ops : INumeric<'T>) x y = ops.Multiply(x,y) 
-
-        let inline foldR f z (a,b) = 
-            let mutable res = z in
-            for i = a to b do
-                res <- f res i
-            res
-
-        let inline sumfR f (a,b) =
-            let mutable res = 0.0 
-            for i = a to b do
-                res <- res + f i
-            res
-          
-
-        let inline sumRGU (ops : INumeric<_>) f r = 
-            let zero = ops.Zero 
-            r |> foldR (fun z k -> add ops z (f k)) zero
-
-        let genericMulDenseMatrix (a:DenseMatrix<_>) (b:DenseMatrix<_>) =
-            let nA = a.NumCols 
-            let mA = a.NumRows
-            let nB = b.NumCols 
-            let mB = b.NumRows
-            if nA<>mB then invalidArg "b" "the two matrices do not have compatible dimensions"
-            let ops = a.ElementOps 
-            let arrA = a.Values 
-            let arrB = b.Values 
-            createDenseMatrixGU a.OpsData mA nB
-              (fun i j -> (0,nA - 1) |> sumRGU ops (fun k -> mul ops (getArray2D arrA i k) (getArray2D arrB k j)))
-
-        let debug = false
-        
-        // SParse matrix multiplication algorithm. inline to get specialization at the 'double' type
-        let inline genericMulSparse zero add mul (a:SparseMatrix<_>) (b:SparseMatrix<_>) =
-            let nA = a.NumCols
-            let mA = a.NumRows
-            let nB = b.NumCols 
-            let mB = b.NumRows
-            if nA<>mB then invalidArg "b" "the two matrices do not have compatible dimensions"
-            let C = new ResizeArray<_>()
-            let jC = new ResizeArray<_>()
-            let MA1 = mA + 1 
-            let offsAcc = Array.zeroCreate MA1
-            let index = Array.zeroCreate mA
-            let temp = Array.create mA zero
-            let ptr = new Dictionary<_,_>(11)
-            if debug then printf "start, #items in result = %d, #offsAcc = %d, mA = %d\n" jC.Count offsAcc.Length mA;
-
-            let mutable mlast = 0
-            for i = 0 to mA-1 do
-                if debug then printf "i = %d, mlast = %d\n" i mlast;
-                offsAcc.[i] <- mlast
-                
-                let kmin1 = a.MinIndexForRow i
-                let kmax1 = a.MaxIndexForRow i
-                if kmin1 < kmax1 then 
-                    let mutable itemp = 0
-                    let mutable ptrNeedsClear = true // clear the ptr table on demand. 
-                    for j = kmin1 to kmax1 - 1 do
-                        if debug then printf "  j = %d\n" j;
-                        let ja_j = a.SparseColumnValues.[j]
-                        let kmin2 = b.MinIndexForRow ja_j
-                        let kmax2 = b.MaxIndexForRow ja_j
-                        for k = kmin2 to kmax2 - 1 do
-                            let jb_k = b.SparseColumnValues.[k]
-                            if debug then printf "    i = %d, j = %d, k = %d, ja_j = %d, jb_k = %d\n" i j k ja_j jb_k;
-                            let va = a.SparseValues.[j] 
-                            let vb = b.SparseValues.[k]
-                            if debug then printf "    va = %O, vb = %O\n" va vb;
-                            let summand = mul va vb
-                            if debug then printf "    summand = %O\n" summand;
-                            if ptrNeedsClear then (ptr.Clear();ptrNeedsClear <- false);
-
-                            if not (ptr.ContainsKey(jb_k)) then
-                                if debug then printf "    starting entry %d\n" jb_k;
-                                ptr.[jb_k] <- itemp
-                                let ptr_jb_k = itemp
-                                temp.[ptr_jb_k] <- summand
-                                index.[ptr_jb_k] <- jb_k
-                                itemp <- itemp + 1
-                            else
-                                if debug then printf "    adding to entry %d\n" jb_k;
-                                let ptr_jb_k = ptr.[jb_k]
-                                temp.[ptr_jb_k] <- add temp.[ptr_jb_k] summand
-                        done
-                    done
-                    if itemp > 0 then 
-                        // Sort by index. 
-                        // REVIEW: avoid the allocations here
-                        let sorted = (temp.[0..itemp-1],index.[0..itemp-1]) ||> Array.zip 
-                        Array.sortInPlaceBy (fun (_,idx) -> idx) sorted
-                        for s = 0 to itemp-1 do
-                            let (v,idx) = sorted.[s]
-                            if debug then printf "  writing value %O at index %d to result matrix\n" v idx;
-                            C.Add(v)
-                            jC.Add(idx)
-                        if debug then printf " itemp = %d, mlast = %d\n" itemp mlast;
-                        mlast <- mlast + itemp 
-            done
-            offsAcc.[mA] <- mlast;
-            if debug then printf "done, #items in result = %d, #offsAcc = %d, mA = %d\n" jC.Count offsAcc.Length mA;
-            SparseMatrix(opsData = a.OpsData,
-                         sparseRowOffsets=offsAcc,
-                         ncols= nB,
-                         columnValues=jC.ToArray(),
-                         sparseValues=C.ToArray())
-
-        let mulSparseMatrixGU (a: SparseMatrix<_>) b =
-            let ops = a.ElementOps 
-            let zero = ops.Zero
-            genericMulSparse zero (add ops) (mul ops) a b
-
-
-        let mulRowVecVecGU (a:RowVector<_>) (b:Vector<_>) =
-            let mA = a.NumCols 
-            let nB = b.NumRows 
-            if mA<>nB then invalidArg "b" "the two vectors do not have compatible dimensions"
-            let ops = a.ElementOps 
-            (0,mA - 1) |> sumRGU ops (fun k -> mul ops a.[k] b.[k])
-
-        let rowvecDenseMatrixGU (x:RowVector<_>) = createDenseMatrixGU x.OpsData 1         x.NumCols (fun _ j -> x.[j]) 
-        let vectorDenseMatrixGU (x:Vector<_>)    = createDenseMatrixGU x.OpsData  x.NumRows 1         (fun i _ -> x.[i]) 
-
-        let mulVecRowVecGU a b = genericMulDenseMatrix (vectorDenseMatrixGU a) (rowvecDenseMatrixGU b)
-
-        let mulRowVecDenseMatrixGU (a:RowVector<_>) (b:DenseMatrix<_>) =
-            let    nA = a.NumCols 
-            let nB = b.NumCols
-            let mB = b.NumRows 
-            if nA<>mB then invalidArg "b" "the two vectors do not have compatible dimensions"
-            let ops = a.ElementOps 
-            let arrA = a.Values 
-            let arrB = b.Values 
-            createRowVecGU a.OpsData nB 
-              (fun j -> (0,nA - 1) |> sumRGU ops (fun k -> mul ops arrA.[k] (getArray2D arrB k j)))
-
-        let mulDenseMatrixVecGU (a:DenseMatrix<_>) (b:Vector<_>) =
-            let nA = a.NumCols 
-            let mA = a.NumRows 
-            let mB    = b.NumRows
-            if nA<>mB then invalidArg "b" "the two inputs do not have compatible dimensions"
-            let ops = b.ElementOps 
-            let arrA = a.Values 
-            let arrB = b.Values 
-            createVecGU b.OpsData mA
-              (fun i -> (0,nA - 1) |> sumRGU ops (fun k -> mul ops (getArray2D arrA i k) arrB.[k]))
-
-        let mulSparseVecGU (a:SparseMatrix<_>) (b:Vector<_>) =
-            let nA = a.NumCols 
-            let mA = a.NumRows 
-            let mB    = b.NumRows 
-            if nA<>mB then invalidArg "b" "the two inputs do not have compatible dimensions"
-            let ops = b.ElementOps 
-            let zero = ops.Zero
-            createVecGU b.OpsData mA (fun i -> 
-                let mutable acc = zero
-                for k = a.MinIndexForRow i to a.MaxIndexForRow i - 1 do
-                    let j = a.SparseColumnValues.[k]
-                    let v = a.SparseValues.[k] 
-                    acc <- add ops acc (mul ops v b.[j]);
-                acc)
-
-        let mulRVSparseMatrixGU (a:RowVector<_>) (b:SparseMatrix<_>) =
-            let nA = b.NumCols
-            let mA = b.NumRows 
-            let mB    = a.NumCols 
-            if mA<>mB then invalidArg "b" "the two inputs do not have compatible dimensions"
-            let ops = b.ElementOps 
-            let arr = createArray nA 
-            zeroizeArray a.OpsData arr nA;
-            for i = 0 to mA - 1 do
-                for k = b.MinIndexForRow i to b.MaxIndexForRow i - 1 do
-                    let j = b.SparseColumnValues.[k]
-                    let v = b.SparseValues.[k] 
-                    arr.[j] <- add ops arr.[j] (mul ops a.[i] v)
-            mkRowVecGU a.OpsData arr
-
-
-        let scaleDenseMatrixGU  k (a:DenseMatrix<_>)  = let ops = a.ElementOps in unaryOpDenseMatrixGU (fun x -> ops.Multiply(k,x)) a
-        let scaleRowVecGU       k (a:RowVector<_>)    = let ops = a.ElementOps in unaryOpRowVecGU (fun x -> ops.Multiply(k,x)) a
-        let scaleVecGU          k (a:Vector<_>)       = let ops = a.ElementOps in unaryOpVectorGU  (fun x -> ops.Multiply(k,x)) a
-        let scaleSparseMatrixGU k (a:SparseMatrix<_>) = let ops = a.ElementOps in unaryOpSparseGU (fun x -> ops.Multiply(k,x)) a
-        let negDenseMatrixGU  (a:DenseMatrix<_>)  = let ops = a.ElementOps in unaryOpDenseMatrixGU (fun x -> ops.Negate(x)) a
-        let negRowVecGU       (a:RowVector<_>)    = let ops = a.ElementOps in unaryOpRowVecGU (fun x -> ops.Negate(x)) a
-        let negVecGU          (a:Vector<_>)       = let ops = a.ElementOps in unaryOpVectorGU  (fun x -> ops.Negate(x)) a
-        let negSparseMatrixGU (a:SparseMatrix<_>) = let ops = a.ElementOps in unaryOpSparseGU (fun x -> ops.Negate(x)) a
-
-        let mapDenseMatrixGU f (a : DenseMatrix<'T>) : DenseMatrix<'T> = 
-            let arrA = a.Values 
-            createDenseMatrixGU a.OpsData a.NumRows a.NumCols (fun i j -> f (getArray2D arrA i j))
-
-        let mapVecGU f (a:Vector<_>) = 
-            let mA= a.NumRows
-            createVecGU a.OpsData mA (fun i -> f a.[i])
-
-        let copyDenseMatrixGU (a : DenseMatrix<'T>) : DenseMatrix<'T> = 
-            let arrA = a.Values 
-            createDenseMatrixGU a.OpsData a.NumRows a.NumCols (fun i j -> getArray2D arrA i j)
-
-        let copyVecGU (a:Vector<_>) = 
-            createVecGU a.OpsData a.NumRows (fun i -> a.[i])
-
-        let copyRowVecGU (a:RowVector<_>) = 
-            createRowVecGU a.OpsData a.NumCols (fun i -> a.[i])
-
-        let toDenseSparseMatrixGU (a:SparseMatrix<_>) = 
-            createDenseMatrixGU a.OpsData a.NumRows a.NumCols  (fun i j -> a.[i,j])
-          
-        let mapiDenseMatrixGU f (a: DenseMatrix<'T>) : DenseMatrix<'T> = 
-            let arrA = a.Values 
-            createDenseMatrixGU a.OpsData a.NumRows a.NumCols (fun i j -> f i j (getArray2D arrA i j))
-
-        let mapiRowVecGU f (a:RowVector<_>) = 
-            createRowVecGU a.OpsData a.NumCols (fun i -> f i a.[i])
-
-        let mapiVecGU f (a:Vector<_>) = 
-            createVecGU a.OpsData a.NumRows (fun i -> f i a.[i])
-
-        let permuteVecGU (p:permutation) (a:Vector<_>) = 
-            createVecGU a.OpsData a.NumRows (fun i -> a.[p i])
-
-        let permuteRowVecGU (p:permutation) (a:RowVector<_>) = 
-            createRowVecGU a.OpsData a.NumCols (fun i -> a.[p i])
-
-        let inline inplace_mapiDenseMatrixGU f (a:DenseMatrix<_>) = 
-            let arrA = a.Values 
-            assignDenseMatrixGU (fun i j -> f i j (getArray2D arrA i j)) a
-
-        let inline inplace_mapiRowVecGU f (a:RowVector<_>) = 
-            assignRowVecGU (fun i -> f i a.[i]) a
-
-        let inline inplace_mapiVecGU f (a:Vector<_>) = 
-            assignVecGU (fun i -> f i a.[i]) a
-
-        let inline foldDenseMatrixGU f z (a:DenseMatrix<_>) =
-            let nA = a.NumCols 
-            let mA = a.NumRows
-            let arrA = a.Values 
-            let mutable acc = z
-            for i = 0 to mA-1 do
-                for j = 0 to nA-1 do 
-                   acc <- f acc (getArray2D arrA i j)
-            acc
-        
-        let inline foldVecGU f z (a:Vector<_>) =
-            let mutable acc = z
-            for i = 0 to a.NumRows-1 do acc <- f acc a.[i]
-            acc
-        
-        let inline foldiDenseMatrixGU f z (a:DenseMatrix<_>) =
-            let nA = a.NumCols 
-            let mA = a.NumRows
-            let arrA = a.Values 
-            let mutable acc = z
-            for i = 0 to mA-1 do
-                for j = 0 to nA-1 do 
-                   acc <- f i j acc (getArray2D arrA i j)
-            acc
-        
-        let inline foldiVecGU f z (a:Vector<_>) =
-            let mA = a.NumRows
-            let mutable acc = z
-            for i = 0 to mA-1 do acc <- f i acc a.[i]
-            acc
-        
-        let rec forallR f (n,m) = (n > m) || (f n && forallR f (n+1,m))
-        let rec existsR f (n,m) = (n <= m) && (f n || existsR f (n+1,m))
-        
-        let foralliDenseMatrixGU pred (a:DenseMatrix<_>) =
-            let nA = a.NumCols 
-            let mA = a.NumRows
-            let arrA = a.Values 
-            (0,mA-1) |> forallR  (fun i ->
-            (0,nA-1) |> forallR  (fun j ->
-            pred i j (getArray2D arrA i j)))
-
-        let foralliVecGU pred (a:Vector<_>) =
-            let mA = a.NumRows
-            (0,mA-1) |> forallR  (fun i ->
-            pred i a.[i])
-
-        let existsiDenseMatrixGU pred (a:DenseMatrix<_>) =
-            let nA = a.NumCols 
-            let mA = a.NumRows
-            let arrA = a.Values 
-            (0,mA-1) |> existsR (fun i ->
-            (0,nA-1) |> existsR (fun j ->
-            pred i j (getArray2D arrA i j)))
-
-        let existsiVecGU pred (a:Vector<_>) =
-            let mA = a.NumRows
-            (0,mA-1) |> existsR (fun i ->
-            pred i a.[i])
-
-        let sumDenseMatrixGU  (a:DenseMatrix<_>) = 
-            let ops = a.ElementOps 
-            foldDenseMatrixGU (fun acc aij -> add ops acc aij) ops.Zero a
-
-        let sumSparseMatrixGU  (a:SparseMatrix<_>) = 
-            let ops = a.ElementOps 
-            a |> nonZeroEntriesSparseMatrixGU |> Seq.fold (fun acc (_,_,aij) -> add ops acc aij) ops.Zero
-
-        let sumVecGU (a:Vector<_>) = 
-            let ops = a.ElementOps 
-            foldVecGU (fun acc ai -> add ops acc ai) ops.Zero a
-
-        let prodDenseMatrixGU (a:DenseMatrix<_>) = 
-            let ops = a.ElementOps 
-            foldDenseMatrixGU (fun acc aij -> mul ops acc aij) ops.One a
-
-        let prodSparseMatrixGU  (a:SparseMatrix<_>) = a |> toDenseSparseMatrixGU |> prodDenseMatrixGU
-
-        let inline fold2DenseMatrixGU f z (a:DenseMatrix<_>) (b:DenseMatrix<_>) =
-            let nA = a.NumCols 
-            let mA = a.NumRows
-            let nB = b.NumCols 
-            let mB = b.NumRows
-            if nA <> nB || mA <> mB then invalidArg "b" "the two matrices do not have compatible dimensions"
-            let arrA = a.Values 
-            let arrB = b.Values 
-            let mutable acc = z
-            for i = 0 to mA-1 do
-                for j = 0 to nA-1 do 
-                   acc <- f acc (getArray2D arrA i j) (getArray2D arrB i j)
-            acc
-
-        let inline fold2VecGU f z (a:Vector<_>) (b:Vector<_>) =
-            let mA = a.NumRows
-            let mB = b.NumRows
-            if  mA <> mB then invalidArg "b" "the two vectors do not have compatible dimensions"
-            let mutable acc = z
-            for i = 0 to mA-1 do acc <- f acc a.[i] b.[i]
-            acc
-
-        let dotDenseMatrixGU (a:DenseMatrix<_>) b =
-            let ops = a.ElementOps 
-            fold2DenseMatrixGU (fun z va vb -> add ops z (mul ops va vb)) ops.Zero a b
-
-        let dotVecGU (a:Vector<_>) b =
-            let ops =   a.ElementOps
-            let zero = ops.Zero 
-            fold2VecGU  (fun z va vb -> add ops z (mul ops va vb)) zero a b 
-
-        let normDenseMatrixGU (a:DenseMatrix<_>) = 
-            let normOps = getNormOps a.ElementOps
-            foldDenseMatrixGU (fun z aij -> z + ((normOps.Norm aij)**2.0)) 0.0 a |> sqrt
-
-        let normSparseMatrixGU (a:SparseMatrix<_>) = 
-            let normOps = getNormOps a.ElementOps
-            a |> nonZeroEntriesSparseMatrixGU |> Seq.fold (fun acc (_,_,aij) -> acc + ((normOps.Norm aij)**2.0)) 0.0 |> sqrt
-
-        let inplaceAddDenseMatrixGU  (a:DenseMatrix<_>) (b:DenseMatrix<_>) = 
-            let ops = a.ElementOps 
-            let arrB = b.Values 
-            inplace_mapiDenseMatrixGU  (fun i j x -> add ops x (getArray2D arrB i j)) a
-        
-        let inplaceAddVecGU  (a:Vector<_>) (b:Vector<_>) = 
-            let ops = a.ElementOps 
-            inplace_mapiVecGU  (fun i x   -> add ops x b.[i]) a
-
-        let inplaceAddRowVecGU (a:RowVector<_>) (b:Vector<_>) = 
-            let ops = a.ElementOps 
-            inplace_mapiRowVecGU (fun i x   -> add ops x b.[i]) a
-
-        let inplaceSubDenseMatrixGU  (a:DenseMatrix<_>) (b:DenseMatrix<_>) = 
-            let ops = a.ElementOps 
-            let arrB = b.Values 
-            inplace_mapiDenseMatrixGU  (fun i j x -> sub ops x (getArray2D  arrB i j)) a
-
-        let inplaceSubVecGU (a:Vector<_>) (b:Vector<_>) = 
-            let ops = a.ElementOps
-            inplace_mapiVecGU  (fun i x   -> sub ops x b.[i]) a
-
-        let inplaceSubRowVecGU (a:RowVector<_>) (b:Vector<_>) = 
-            let ops = a.ElementOps 
-            inplace_mapiRowVecGU (fun i x   -> sub ops x b.[i]  ) a
-
-        let inplaceCptMulDenseMatrixGU  (a:DenseMatrix<_>) (b:DenseMatrix<_>) = 
-            let ops = a.ElementOps 
-            let arrB = b.Values 
-            inplace_mapiDenseMatrixGU  (fun i j x -> mul ops x (getArray2D  arrB i j)) a
-
-        let inplaceCptMulVecGU (a:Vector<_>) (b:Vector<_>) = 
-            let ops = a.ElementOps  
-            inplace_mapiVecGU  (fun i x   -> mul ops x b.[i]) a
-
-        let inplaceCptMulRowVecGU (a:RowVector<_>) (b:Vector<_>) = 
-            let ops = a.ElementOps 
-            inplace_mapiRowVecGU (fun i x   -> mul ops x b.[i]  ) a
-
-        let inplaceScaleDenseMatrixGU  x (a:DenseMatrix<_>) = 
-            let ops = a.ElementOps 
-            inplace_mapiDenseMatrixGU  (fun _ _ y -> ops.Multiply(x,y)) a
-
-        let inplaceScaleVecGU  x (a:Vector<_>) = 
-            let ops = a.ElementOps  
-            inplace_mapiVecGU  (fun _ y   -> ops.Multiply(x,y)) a
-
-        let inplaceScaleRowVecGU x (a:RowVector<_>) = 
-            let ops = a.ElementOps 
-            inplace_mapiRowVecGU (fun _ y   -> ops.Multiply(x,y)) a
-
-
-        let wrapList (pre,mid,post,trim) show l = 
-            let post = if trim then "; ..." + post else post
-            match l with 
-            | []    -> [pre;post]
-            | [x]   -> [pre;show x;post]
-            | x::xs -> [pre;show x] @ (List.collect (fun x -> [mid;show x]) xs) @ [post]
-
-        let showItem opsData  x = 
-            try 
-              let ops = opsOfOpsData opsData 
-              ops.ToString(x,"g10",System.Globalization.CultureInfo.InvariantCulture) 
-            with :? System.NotSupportedException -> (box x).ToString()
-        
-        let mapR f (n,m) = if m < n then [] else List.init (m-n+1) (fun i -> f (n+i))
-
-        let primShowDenseMatrixGU (sepX,sepR) (a : DenseMatrix<'e>) =
-            let nA = min a.NumCols DenseMaxDisplay
-            let mA = min a.NumRows DenseMaxDisplay
-            let ops = a.OpsData 
-            let showLine i = wrapList ("[",";","]", a.NumCols > nA) (showItem ops) ((0,nA-1) |> mapR  (fun j -> a.[i,j])) |> Array.ofList |> System.String.Concat
-            wrapList (string nA + " " + string mA + "matrix [",";"+sepX,"]"+sepR, a.NumRows > mA) showLine [0..mA-1] |> Array.ofList |> System.String.Concat
-
-        let showDenseMatrixGU     m = primShowDenseMatrixGU ("\n","\n") m
-        let debugShowDenseMatrixGU m = primShowDenseMatrixGU (""  ,""  ) m
-        
-        let showVecGU s (a : Vector<_>) =
-            let mA = min a.NumRows VectorMaxDisplay
-            let ops = a.OpsData 
-            wrapList (s+" [",";","]",a.NumRows > mA) (showItem ops) ((0,mA-1) |> mapR  (fun i -> a.[i])) |> Array.ofList |> System.String.Concat 
-
-        let showRowVecGU s (a : RowVector<_>) =
-            let mA = min a.NumCols VectorMaxDisplay
-            let ops = a.OpsData 
-            wrapList (s+" [",";","]",a.NumCols > mA) (showItem ops) ((0,mA-1) |> mapR  (fun i -> a.[i])) |> Array.ofList |> System.String.Concat 
-
-
-    /// Implementations of operations specific to floating point types
-    module DoubleImpl = 
-
-        module GU = GenericImpl
-        open Instances
-        
-        // Element type OpsData
-        //type elem = float
-        let zero = 0.0
-        let one  = 1.0
-        let inline sub (x:float) (y:float) = x - y
-        let inline add (x:float) (y:float) = x + y
-        let inline mul (x:float) (y:float) = x * y
-        let inline neg (x:float) = -x
-
-        // Specialized: these know the relevant set of 
-        // ops without doing a table lookup based on runtime type
-        let FloatOps = Some (FloatNumerics :> INumeric<float>)
-        let inline initDenseMatrixDS m n f = GU.createDenseMatrixGU FloatOps m n f
-        let inline createRowVecDS m f      = GU.createRowVecGU      FloatOps m f
-        let inline createVecDS m f         = GU.createVecGU         FloatOps m f
-        let inline mkDenseMatrixDS  arr    = GU.mkDenseMatrixGU     FloatOps arr
-        let inline mkRowVecDS arr          = GU.mkRowVecGU          FloatOps arr
-        let inline mkVecDS  arr            = GU.mkVecGU             FloatOps arr
-        let inline listDenseMatrixDS  ll   = GU.listDenseMatrixGU   FloatOps ll
-        let inline listRowVecDS l          = GU.listRowVecGU        FloatOps l
-        let inline listVecDS  l            = GU.listVecGU           FloatOps l
-        let inline seqDenseMatrixDS  ll    = GU.seqDenseMatrixGU    FloatOps ll
-        let inline seqRowVecDS l           = GU.seqRowVecGU         FloatOps l
-        let inline seqVecDS  l             = GU.seqVecGU            FloatOps l
-
-        let constDenseMatrixDS  m n x      = GU.createDenseMatrixGU  FloatOps m n (fun _ _ -> x)
-        let constRowVecDS m x              = GU.createRowVecGU FloatOps m   (fun _ -> x)
-        let constVecDS  m x                = GU.createVecGU  FloatOps m   (fun _ -> x)
-        let scalarDenseMatrixDS   x        = constDenseMatrixDS  1 1 x 
-        let scalarRowVecDS  x              = constRowVecDS 1   x 
-        let scalarVecDS   x                = constVecDS  1   x 
-
-        // Beware - when compiled with non-generic code createArray2D creates an array of null values,
-        // not zero values. Hence the optimized version can only be used when compiling with generics.
-        let inline zeroDenseMatrixDS m n = 
-          let arr = GU.createArray2D m n 
-          GU.mkDenseMatrixGU FloatOps arr
-        // Specialized: these inline down to the efficient loops we need
-        let addDenseMatrixDS     a b = GU.binaryOpDenseMatrixGU  add a b
-        let addSparseDS     a b = GU.binaryOpSparseMatrixGU  add a b
-        let addRowVecDS    a b = GU.binaryOpRowVecGU add a b
-        let addVecDS     a b = GU.binaryOpVecGU  add a b
-        let subDenseMatrixDS     a b = GU.binaryOpDenseMatrixGU  sub a b 
-        let subSparseDS     a b = GU.binaryOpSparseMatrixGU  sub a b 
-        let mulSparseDS     a b = GU.genericMulSparse zero add mul a b
-        let subRowVecDS    a b = GU.binaryOpRowVecGU sub a b 
-        let subVecDS     a b = GU.binaryOpVecGU  sub a b 
-        let cptMulDenseMatrixDS  a b = GU.binaryOpDenseMatrixGU  mul a b
-        let cptMulSparseDS  a b = GU.binaryOpSparseMatrixGU  mul a b
-        let cptMulRowVecDS a b = GU.binaryOpRowVecGU mul a b
-        let cptMulVecDS  a b = GU.binaryOpVecGU  mul a b
-        type smatrix = SparseMatrix<float>
-        type dmatrix = DenseMatrix<float>
-        type vector = Vector<float>
-        type rowvec = RowVector<float>
-        let cptMaxDenseMatrixDS  (a:dmatrix) (b:dmatrix) = GU.binaryOpDenseMatrixGU  max a b
-        let cptMinDenseMatrixDS  (a:dmatrix) (b:dmatrix) = GU.binaryOpDenseMatrixGU  min a b
-        let cptMaxSparseDS  (a:smatrix) (b:smatrix) = GU.binaryOpSparseMatrixGU  max a b
-        let cptMinSparseDS  (a:smatrix) (b:smatrix) = GU.binaryOpSparseMatrixGU  min a b
-        let cptMaxVecDS  (a:vector) (b:vector) = GU.binaryOpVecGU  max a b
-        let cptMinVecDS  (a:vector) (b:vector) = GU.binaryOpVecGU  min a b
-
-        // Don't make any mistake about these ones re. performance.
-        let mulDenseMatrixDS (a:dmatrix) (b:dmatrix) =
-            let nA = a.NumCols 
-            let mA = a.NumRows
-            let nB = b.NumCols 
-            let mB = b.NumRows
-            if nA<>mB then invalidArg "b" "the two matrices do not have compatible dimensions"
-            let arr = GU.createArray2D mA nB 
-            let arrA = a.Values 
-            let arrB = b.Values 
-            for i = 0 to mA - 1 do 
-                for j = 0 to nB - 1 do 
-                    let mutable r = 0.0 
-                    for k = 0 to mB - 1 do 
-                        r <- r + mul (GU.getArray2D arrA i k) (GU.getArray2D arrB k j)
-                    GU.setArray2D arr i j r
-            mkDenseMatrixDS arr
-
-        let mulRowVecDenseMatrixDS (a:rowvec) (b:dmatrix) =
-            let nA = a.NumCols 
-            let nB = b.NumCols 
-            let mB = b.NumRows
-            if nA<>mB then invalidArg "b" "the two inputs do not have compatible dimensions"
-            let arr = Array.zeroCreate nB 
-            let arrA = a.Values 
-            let arrB = b.Values 
-            for j = 0 to nB - 1 do 
-                let mutable r = 0.0 
-                for k = 0 to mB - 1 do 
-                    r <- r + mul arrA.[k] (GU.getArray2D arrB k j)
-                arr.[j] <- r
-            mkRowVecDS arr
-
-        let mulDenseMatrixVecDS (a:dmatrix) (b:vector) =
-            let nA = a.NumCols 
-            let mA = a.NumRows
-            let mB = b.NumRows 
-            if nA<>mB then invalidArg "b" "the two inputs do not have compatible dimensions"
-            let arr = Array.zeroCreate mA 
-            let arrA = a.Values 
-            let arrB = b.Values 
-            for i = 0 to mA - 1 do 
-                let mutable r = 0.0 
-                for k = 0 to nA - 1 do 
-                    r <- r + mul (GU.getArray2D arrA i k) arrB.[k]
-                arr.[i] <- r
-            mkVecDS arr
-
-        let mulRowVecVecDS (a:rowvec) (b:vector) =
-            let nA = a.NumCols 
-            let mB = b.NumRows 
-            if nA<>mB then invalidArg "b" "the two vectors do not have compatible dimensions"
-            let arrA = a.Values 
-            let arrB = b.Values 
-            let mutable r = 0.0 
-            for k = 0 to nA - 1 do 
-                r <- r + mul arrA.[k] arrB.[k]
-            r
-
-        let rowvecDenseMatrixDS (x:rowvec) = initDenseMatrixDS 1          x.NumCols (fun _ j -> x.[j]) 
-        let vectorDenseMatrixDS (x:vector) = initDenseMatrixDS x.NumRows  1         (fun i _ -> x.[i]) 
-        let mulVecRowVecDS a b = mulDenseMatrixDS (vectorDenseMatrixDS a) (rowvecDenseMatrixDS b) 
-
-        let scaleDenseMatrixDS   k m = GU.unaryOpDenseMatrixGU  (fun x -> mul k x) m
-        let scaleSparseDS   k m = GU.unaryOpSparseGU  (fun x -> mul k x) m
-        let scaleRowVecDS  k m = GU.unaryOpRowVecGU (fun x -> mul k x) m
-        let scaleVecDS   k m = GU.unaryOpVectorGU  (fun x -> mul k x) m
-        let negDenseMatrixDS     m   = GU.unaryOpDenseMatrixGU  (fun x -> neg x) m
-        let negSparseDS     m   = GU.unaryOpSparseGU  (fun x -> neg x) m
-        let negRowVecDS    m   = GU.unaryOpRowVecGU (fun x -> neg x) m
-        let negVecDS     m   = GU.unaryOpVectorGU  (fun x -> neg x) m
-
-        let traceDenseMatrixDS (a:dmatrix) =
-            let nA = a.NumCols 
-            let mA = a.NumRows
-            if nA<>mA then invalidArg "a" "expected a square matrix";
-            let arrA = a.Values 
-            (0,nA-1) |> GU.sumfR (fun i -> GU.getArray2D arrA i i) 
-
-        let sumDenseMatrixDS  a = GU.foldDenseMatrixGU add zero a
-        let sumVecDS   a = GU.foldVecGU  add zero a
-        let prodDenseMatrixDS a = GU.foldDenseMatrixGU mul one  a
-        let prodVecDS  a = GU.foldVecGU  mul one  a
-
-        let dotDenseMatrixDS a b = GU.fold2DenseMatrixGU (fun z va vb -> add z (mul va vb)) zero a b
-        let dotVecDS a b = GU.fold2VecGU (fun z va vb -> add z (mul va vb)) zero a b
-        let sumfDenseMatrixDS  f m = GU.foldDenseMatrixGU (fun acc aij -> add acc (f aij)) zero m
-        let normDenseMatrixDS m = sqrt (sumfDenseMatrixDS (fun x -> x*x) m)
-
-        let inplaceAddDenseMatrixDS  a (b:DenseMatrix<_>) = let arrB = b.Values  in GU.inplace_mapiDenseMatrixGU  (fun i j x -> x + GU.getArray2D arrB i j) a
-        let inplaceAddVecDS    a (b:Vector<_>) = let arrB = b.Values  in GU.inplace_mapiVecGU  (fun i x   -> x + arrB.[i]) a
-        let inplace_addRowVecDS a (b:RowVector<_>) = let arrB = b.Values in GU.inplace_mapiRowVecGU (fun i x   -> x + arrB.[i]) a
-        let inplaceSubDenseMatrixDS  a (b:DenseMatrix<_>) = let arrB = b.Values  in GU.inplace_mapiDenseMatrixGU  (fun i j x -> x - GU.getArray2D  arrB i j) a
-        let inplaceSubVecDS  a (b:Vector<_>) = let arrB = b.Values  in GU.inplace_mapiVecGU  (fun i x   -> x - arrB.[i]) a
-        let inplace_subRowVecDS a (b:RowVector<_>) = let arrB = b.Values in GU.inplace_mapiRowVecGU (fun i x   -> x - arrB.[i]) a
-        let inplaceCptMulDenseMatrixDS  a (b:DenseMatrix<_>) = let arrB = b.Values  in GU.inplace_mapiDenseMatrixGU  (fun i j x -> x * GU.getArray2D arrB i j) a
-        let inplaceCptMulVecDS  a (b:Vector<_>) = let arrB = b.Values  in GU.inplace_mapiVecGU  (fun i x   -> x * arrB.[i]) a
-        let inplace_cptMulRowVecDS a (b:RowVector<_>) = let arrB = b.Values in GU.inplace_mapiRowVecGU (fun i x   -> x * arrB.[i]) a
-        let inplaceScaleDenseMatrixDS  (a:float) b = GU.inplace_mapiDenseMatrixGU  (fun _ _ x -> a * x) b
-        let inplaceScaleVecDS  (a:float) b = GU.inplace_mapiVecGU  (fun _ x   -> a * x) b
-        let inplace_scaleRowVecDS (a:float) b = GU.inplace_mapiRowVecGU (fun _ x   -> a * x) b
-
-
-
-    /// Generic operations that, when used on floating point types, use the specialized versions in DoubleImpl
-    module SpecializedGenericImpl = 
-
-        open Microsoft.FSharp.Math.Instances
-        open Microsoft.FSharp.Math.GlobalAssociations
-
-        module GU = GenericImpl
-        module DS = DoubleImpl
-
-          
-        type smatrix = SparseMatrix<float>
-        type dmatrix = DenseMatrix<float>
-        type vector = Vector<float>
-        type rowvec = RowVector<float>
-        let inline dense x = DenseRepr(x)
-        let inline sparse x = SparseRepr(x)
-        let inline createMx  ops rows columns f = GU.createDenseMatrixGU ops rows columns f |> dense
-        let inline createVx  ops m f   = GU.createVecGU ops m f
-        let inline createRVx ops m f   = GU.createRowVecGU ops m f
-
-        let nonZeroEntriesM a   = 
-            match a with 
-            | DenseRepr a -> GU.nonzeroEntriesDenseMatrixGU a 
-            | SparseRepr a -> GU.nonZeroEntriesSparseMatrixGU a 
-
-        /// Merge two sorted sequences
-        let mergeSorted cf (s1: seq<'T>) (s2: seq<'b>) =
-            seq { use e1 = s1.GetEnumerator()
-                  use e2 = s2.GetEnumerator()
-                  let havee1 = ref (e1.MoveNext())
-                  let havee2 = ref (e2.MoveNext())
-                  while !havee1 || !havee2 do
-                    if !havee1 && !havee2 then
-                        let v1 = e1.Current
-                        let v2 = e2.Current
-                        let c = cf v1 v2 
-                        if c < 0 then 
-                            do havee1 := e1.MoveNext()
-                            yield Some(v1),None
-                        elif c = 0 then
-                            do havee1 := e1.MoveNext()
-                            do havee2 := e2.MoveNext()
-                            yield Some(v1),Some(v2)
-                        else 
-                            do havee2 := e2.MoveNext()
-                            yield (None,Some(v2))
-                    elif !havee1 then 
-                        let v1 = e1.Current
-                        do havee1 := e1.MoveNext()
-                        yield (Some(v1),None)
-                    else 
-                        let v2 = e2.Current
-                        do havee2 := e2.MoveNext()
-                        yield (None,Some(v2)) }
-
-        /// Non-zero entries from two sequences
-        let mergedNonZeroEntriesM  (a:Matrix<_>) (b:Matrix<_>) = 
-            let ops = a.ElementOps 
-            let zero = ops.Zero
-            mergeSorted (fun (i1,j1,_) (i2,j2,_) -> let c = compare i1 i2 in if c <> 0 then c else compare j1 j2) (nonZeroEntriesM a) (nonZeroEntriesM b)
-            |> Seq.map (function | Some(i,j,v1),Some(_,_,v2) -> (v1,v2)
-                                 | Some(i,j,v1),None         -> (v1,zero)
-                                 | None,        Some(i,j,v2) -> (zero,v2)
-                                 | None,        None          -> failwith "unreachable")
-
-
-        
-        // Creation
-        let listM    xss : Matrix<'T>    = GU.listDenseMatrixGU opsdata<'T> xss |> dense
-        let listV    xss : Vector<'T>    = GU.listVecGU         opsdata<'T> xss
-        let listRV   xss : RowVector<'T> = GU.listRowVecGU      opsdata<'T> xss
-
-        let arrayM    xss : Matrix<'T>    = GU.mkDenseMatrixGU  opsdata<'T> (Array2D.copy xss) |> dense
-        let arrayV    xss : Vector<'T>    = GU.mkVecGU          opsdata<'T> (Array.copy xss)
-        let arrayRV   xss : RowVector<'T> = GU.mkRowVecGU       opsdata<'T> (Array.copy xss)
-
-        let seqM    xss : Matrix<'T>    = GU.seqDenseMatrixGU   opsdata<'T> xss |> dense
-        let seqV    xss : Vector<'T>    = GU.seqVecGU           opsdata<'T> xss
-        let seqRV   xss : RowVector<'T> = GU.seqRowVecGU        opsdata<'T> xss
-
-        let initM  m n f : Matrix<'T>    = GU.createDenseMatrixGU opsdata<'T> m n f |> dense
-        let initRV m   f : RowVector<'T> = GU.createRowVecGU      opsdata<'T> m   f
-        let initV  m   f : Vector<'T>    = GU.createVecGU         opsdata<'T> m   f
-
-        let constM  m n x : Matrix<'T>    = GU.createConstDenseMatrixGU opsdata<'T> m n x |> dense
-        let constRV m   x : RowVector<'T> = GU.createConstRowVecGU      opsdata<'T> m   x
-        let constV  m   x : Vector<'T>    = GU.createConstVecGU         opsdata<'T> m   x
-
-        let inline inplaceAssignM  f a = 
-            match a with 
-            | SparseRepr _ -> sparseNotMutable()
-            | DenseRepr a -> GU.assignDenseMatrixGU  f a
-        let inline assignV  f a = GU.assignVecGU  f a
-
-        let coerce2 x = unbox(box(x))
-        let loosenDM (x: dmatrix) : DenseMatrix<_>  = coerce2 x
-        let loosenSM (x: smatrix) : SparseMatrix<_> = coerce2 x
-        let loosenV  (x: vector)  : Vector<_>       = coerce2 x
-        let loosenRV (x: rowvec)  : RowVector<_>    = coerce2 x
-        let loosenF  (x: float)   : 'T              = coerce2 x
-
-        let tightenDM (x: DenseMatrix<_>)  : dmatrix = coerce2 x
-        let tightenSM (x: SparseMatrix<_>) : smatrix = coerce2 x
-        let tightenV  (x: Vector<_>)       : vector  = coerce2 x
-        let tightenRV (x: RowVector<_>)    : rowvec  = coerce2 x
-        let tightenF  (x: 'T)              : float   = coerce2 x
-
-        let zeroM m n = 
-            let arr = GU.createArray2D m n
-            // This is quite performance critical
-            // Avoid assigining zeros into the array
-            match box arr with 
-            | :? (float[,])   as arr -> GU.mkDenseMatrixGU DS.FloatOps arr |> loosenDM |> dense
-            | _ -> 
-            GU.zeroizeDenseMatrixGUA arr m n  |> dense
-
-        let zeroV m  : Vector<'T> = 
-            let arr = GU.createArray m 
-            // Avoid assigining zeros into the array
-            match box (arr: 'T[]) with 
-            | :? (float[])   as arr -> GU.mkVecGU DS.FloatOps arr |> loosenV
-            | _ -> 
-            GU.zeroizeVecGUA arr m
-
-        let zeroRV m  : RowVector<'T> = 
-            let arr = GU.createArray m 
-            // Avoid assigining zeros into the array
-            match box (arr: 'T[]) with 
-            | :? (float[])   as arr -> GU.mkRowVecGU DS.FloatOps arr |> loosenRV
-            | _ -> 
-            GU.zeroizeRowVecGUA arr m
-            
-        let initNumericM m n f   = 
-            let arr = GU.createArray2D m n 
-            let opsData = opsdata<'T> 
-            let ops = GU.opsOfOpsData opsData 
-            GU.assignArray2D m n (f ops) arr;
-            GU.mkDenseMatrixGU opsData arr |> dense
-
-        let identityM m   = 
-            let arr = GU.createArray2D m m 
-            // This is quite performance critical
-            // Avoid assigining zeros into the array
-            match box arr with 
-            | :? (float[,])   as arr -> 
-                for i = 0 to m - 1 do 
-                   arr.[i,i] <- 1.0 
-                GU.mkDenseMatrixGU DS.FloatOps arr |> loosenDM |> dense
-            | _ -> 
-            let opsData = opsdata<'T> 
-            let ops = GU.opsOfOpsData opsData 
-            let zero = ops.Zero 
-            let one = ops.One 
-            GU.assignArray2D m m (fun i j -> if i = j then one else zero) arr;
-            GU.mkDenseMatrixGU opsData arr |> dense
-
-        let createNumericV m f  : Vector<'T> = 
-            let arr = GU.createArray m 
-            let opsData = opsdata<'T> 
-            let ops = GU.opsOfOpsData opsData 
-            GU.assignArray m (f ops) arr;
-            GU.mkVecGU opsData arr
-            
-        let scalarM   x = constM 1 1 x 
-        let scalarRV  x = constRV 1 x 
-        let scalarV   x = constV 1 x 
-
-        let diagnM (v:Vector<_>) n = 
-            let ops = v.ElementOps
-            let zero = ops.Zero 
-            let nV = v.NumRows + (if n < 0 then -n else n) 
-            createMx v.OpsData nV nV (fun i j -> if i+n=j then v.[i] else zero)
-
-        let diagM v = diagnM v 0
-
-        let constDiagM  n x : Matrix<'T> = 
-            let opsData = opsdata<'T> 
-            let ops = GU.opsOfOpsData opsData 
-            let zero = ops.Zero 
-            createMx opsData n n (fun i j -> if i=j then x else zero) 
-
-        // Note: we drop sparseness on pointwise multiplication of sparse and dense.
-        let inline binaryOpM opDenseDS opDenseGU opSparseDS opSparseMatrixGU a b = 
-            match a,b with 
-            | DenseRepr a,DenseRepr b -> 
-                match box a with 
-                | (:? dmatrix as a) -> opDenseDS   a (tightenDM b) |> loosenDM |> dense
-                | _                 -> opDenseGU a b                           |> dense
-            | SparseRepr a,SparseRepr b ->
-                match box a with 
-                | (:? smatrix as a) -> opSparseDS a (tightenSM b) |> loosenSM |> sparse
-                | _                 -> opSparseMatrixGU a b                         |> sparse
-            | SparseRepr a, DenseRepr b     -> opDenseGU (GU.toDenseSparseMatrixGU a) b         |> dense
-            | DenseRepr  a, SparseRepr b    -> opDenseGU a (GU.toDenseSparseMatrixGU b)         |> dense
-
-        let inline unaryOpM opDenseDS opDenseGU opSparseDS opSparseMatrixGU  b = 
-            match b with 
-            | DenseRepr b -> 
-                match box b with 
-                | (:? dmatrix as b)  -> opDenseDS b |> loosenDM |> dense
-                | _                  -> opDenseGU b             |> dense
-            | SparseRepr b ->             
-                match box b with 
-                | (:? smatrix as b) -> opSparseDS b |> loosenSM |> sparse
-                | _                 -> opSparseMatrixGU b             |> sparse
-
-        let inline floatUnaryOpM opDenseDS opDenseGU opSparseDS opSparseMatrixGU  b = 
-            match b with 
-            | DenseRepr b -> 
-                match box b with 
-                | (:? dmatrix as b)  -> opDenseDS b |> loosenF
-                | _                  -> opDenseGU b             
-            | SparseRepr b ->             
-                match box b with 
-                | (:? smatrix as b) -> opSparseDS b |> loosenF 
-                | _                 -> opSparseMatrixGU b             
-
-        let addM a b = binaryOpM DS.addDenseMatrixDS GU.addDenseMatrixGU DS.addSparseDS GU.addSparseMatrixGU a b
-        let subM a b = binaryOpM DS.subDenseMatrixDS GU.subDenseMatrixGU DS.subSparseDS GU.subSparseMatrixGU a b
-        let mulM a b = binaryOpM DS.mulDenseMatrixDS GU.genericMulDenseMatrix DS.mulSparseDS GU.mulSparseMatrixGU a b
-        let cptMulM a b = binaryOpM DS.cptMulDenseMatrixDS GU.cptMulDenseMatrixGU DS.cptMulSparseDS GU.cptMulSparseMatrixGU a b
-        let cptMaxM a b = binaryOpM DS.cptMaxDenseMatrixDS GU.cptMaxDenseMatrixGU DS.cptMaxSparseDS GU.cptMaxSparseMatrixGU a b
-        let cptMinM a b = binaryOpM DS.cptMinDenseMatrixDS GU.cptMinDenseMatrixGU DS.cptMinSparseDS GU.cptMinSparseMatrixGU a b
-
-        let addRV a b = 
-            match box a with 
-            | (:? rowvec as a) -> DS.addRowVecDS a (tightenRV b) |> loosenRV
-            | _                -> GU.addRowVecGU a b
-
-        let addV a b = 
-            match box a with 
-            | (:? vector as a) -> DS.addVecDS a (tightenV b) |> loosenV
-            | _                -> GU.addVecGU a b
-
-        let subRV a b = 
-            match box a with 
-            | (:? rowvec as a) -> DS.subRowVecDS   a (tightenRV b) |> loosenRV
-            | _                -> GU.subRowVecGU a b
-
-        let subV a b = 
-            match box a with 
-            | (:? vector as a) -> DS.subVecDS   a (tightenV b) |> loosenV
-            | _                -> GU.subVecGU a b
-
-        let mulRVM a b = 
-            match b with 
-            | DenseRepr b -> 
-                match box a with 
-                | (:? rowvec as a) -> DS.mulRowVecDenseMatrixDS   a (tightenDM b) |> loosenRV
-                | _                -> GU.mulRowVecDenseMatrixGU a b
-            | SparseRepr b -> GU.mulRVSparseMatrixGU a b
-
-        let mulMV a b = 
-            match a with 
-            | DenseRepr a -> 
-                match box a with 
-                | (:? dmatrix as a) -> DS.mulDenseMatrixVecDS   a (tightenV b) |> loosenV
-                | _                 -> GU.mulDenseMatrixVecGU a b
-            | SparseRepr a -> GU.mulSparseVecGU a b 
-
-        let mulRVV a b = 
-            match box a with 
-            | (:? rowvec as a) -> DS.mulRowVecVecDS   a (tightenV b) |> loosenF
-            | _                -> GU.mulRowVecVecGU a b
-
-        let mulVRV a b = 
-            match box a with 
-            | (:? vector as a) -> DS.mulVecRowVecDS   a (tightenRV b) |> loosenDM |> dense
-            | _                -> GU.mulVecRowVecGU a b |> dense
-
-        let cptMulRV a b = 
-            match box a with 
-            | (:? rowvec as a) -> DS.cptMulRowVecDS   a (tightenRV b) |> loosenRV
-            | _                -> GU.cptMulRowVecGU a b
-
-        let cptMulV a b = 
-            match box a with 
-            | (:? vector as a) -> DS.cptMulVecDS   a (tightenV b) |> loosenV
-            | _                -> GU.cptMulVecGU a b
-
-        let cptMaxV a b = 
-            match box a with 
-            | (:? vector as a) -> DS.cptMaxVecDS   a (tightenV b) |> loosenV
-            | _                -> GU.cptMaxVecGU a b
-
-        let cptMinV a b = 
-            match box a with 
-            | (:? vector as a) -> DS.cptMinVecDS   a (tightenV b) |> loosenV
-            | _                -> GU.cptMinVecGU a b
-
-        let scaleM a b = unaryOpM (fun b -> DS.scaleDenseMatrixDS (tightenF a) b) (GU.scaleDenseMatrixGU a)
-                                  (fun b -> DS.scaleSparseDS (tightenF a) b) (GU.scaleSparseMatrixGU a) b
-
-        let scaleRV a b = 
-            match box b with 
-            | (:? rowvec as b)  -> DS.scaleRowVecDS (tightenF a) b |> loosenRV 
-            | _                 -> GU.scaleRowVecGU a b
-
-        let scaleV a b = 
-            match box b with 
-            | (:? vector as b)  -> DS.scaleVecDS (tightenF a) b |> loosenV
-            | _                 -> GU.scaleVecGU a b
-
-        let dotM a b = 
-            match a,b with 
-            | DenseRepr a,DenseRepr b -> 
-                match box b with 
-                | (:? dmatrix as b)  -> DS.dotDenseMatrixDS   (tightenDM a) b |> loosenF
-                | _                  -> GU.dotDenseMatrixGU a b
-            | _ ->  
-                let ops = a.ElementOps 
-                mergedNonZeroEntriesM a b |> Seq.fold (fun z (va,vb) -> GU.add ops z (GU.mul ops va vb)) ops.Zero 
-
-        let dotV a b = 
-            match box b with 
-            | (:? vector as b)  -> DS.dotVecDS   (tightenV a) b |> loosenF
-            | _                 -> GU.dotVecGU a b
-
-        let negM a = unaryOpM DS.negDenseMatrixDS GU.negDenseMatrixGU DS.negSparseDS GU.negSparseMatrixGU a
-
-        let negRV a = 
-            match box a with 
-            | (:? rowvec as a) -> DS.negRowVecDS a |> loosenRV
-            | _               ->  GU.negRowVecGU a
-
-        let negV a = 
-            match box a with 
-            | (:? vector as a) -> DS.negVecDS a |> loosenV
-            | _               ->  GU.negVecGU a
-
-        let traceMGU (a:Matrix<_>) =
-            let nA = a.NumCols  
-            let mA = a.NumRows 
-            if nA<>mA then invalidArg "a" "expected a square matrix";
-            let ops = a.ElementOps 
-            (0,nA-1) |> GU.sumRGU ops (fun i -> a.[i,i]) 
-
-        let traceM a = floatUnaryOpM DS.traceDenseMatrixDS (dense >> traceMGU) (sparse >> traceMGU) (sparse >> traceMGU) a
-        let sumM a = floatUnaryOpM DS.sumDenseMatrixDS GU.sumDenseMatrixGU GU.sumSparseMatrixGU GU.sumSparseMatrixGU a
-        let prodM a = floatUnaryOpM DS.prodDenseMatrixDS GU.prodDenseMatrixGU GU.prodSparseMatrixGU GU.prodSparseMatrixGU a
-        let normM a = floatUnaryOpM DS.normDenseMatrixDS GU.normDenseMatrixGU GU.normSparseMatrixGU GU.normSparseMatrixGU a
-
-        let opsM a = 
-            match a with 
-            | DenseRepr a -> a.OpsData 
-            | SparseRepr a -> a.OpsData 
-        
-        let transM a = 
-            match a with 
-            | DenseRepr a -> 
-                // rows of transposed matrix = columns of original matrix and vice versa
-                createMx a.OpsData a.NumCols a.NumRows (fun i j -> a.[j,i])
-            | SparseRepr a -> 
-                a |> GU.nonZeroEntriesSparseMatrixGU  |> Seq.map (fun (i,j,v) -> (j,i,v)) |> GU.initSparseMatrixGU a.NumCols a.NumRows a.OpsData |> sparse
-        
-        let permuteRows (p: permutation) a =
-            match a with
-            | DenseRepr a ->
-                createMx a.OpsData a.NumRows a.NumCols (fun i j -> a.[p i,j])
-            | SparseRepr a ->
-                a |> GU.nonZeroEntriesSparseMatrixGU  |> Seq.map (fun (i,j,v) -> (p i,j,v)) |> GU.initSparseMatrixGU a.NumCols a.NumRows a.OpsData |> sparse
-
-        let permuteColumns (p: permutation) a =
-            match a with
-            | DenseRepr a ->
-                createMx a.OpsData a.NumRows a.NumCols (fun i j -> a.[i,p j])
-            | SparseRepr a ->
-                a |> GU.nonZeroEntriesSparseMatrixGU  |> Seq.map (fun (i,j,v) -> (i,p j,v)) |> GU.initSparseMatrixGU a.NumCols a.NumRows a.OpsData |> sparse
-
-        let transRV (a:RowVector<_>) = 
-            createVx a.OpsData  a.NumCols (fun i -> a.[i])
-
-        let transV (a:Vector<_>)  = 
-            createRVx a.OpsData a.NumRows (fun i -> a.[i])
-
-        let inplaceAddM a b = 
-            match a,b with 
-            | DenseRepr a,DenseRepr b -> 
-                match box a with 
-                | (:? dmatrix as a) -> DS.inplaceAddDenseMatrixDS   a (tightenDM b)
-                | _                 -> GU.inplaceAddDenseMatrixGU a b
-            | _ -> sparseNotMutable()
-
-        let inplaceAddV a b = 
-            match box a with 
-            | (:? vector as a) -> DS.inplaceAddVecDS   a (tightenV b)
-            | _                -> GU.inplaceAddVecGU a b
-
-        let inplaceSubM a b = 
-            match a,b with 
-            | DenseRepr a,DenseRepr b -> 
-                match box a with 
-                | (:? dmatrix as a) -> DS.inplaceSubDenseMatrixDS   a (tightenDM b)
-                | _                -> GU.inplaceSubDenseMatrixGU a b
-            | _ -> sparseNotMutable()
-
-        let inplaceSubV a b = 
-            match box a with 
-            | (:? vector as a) -> DS.inplaceSubVecDS   a (tightenV b)
-            | _                -> GU.inplaceSubVecGU a b
-
-
-        let inplaceCptMulM a b = 
-            match a,b with 
-            | DenseRepr a,DenseRepr b -> 
-                match box a with 
-                | (:? dmatrix as a) -> DS.inplaceCptMulDenseMatrixDS   a (tightenDM b)
-                | _                -> GU.inplaceCptMulDenseMatrixGU a b
-            | _ -> sparseNotMutable()
-
-        let inplaceCptMulV a b = 
-            match box a with 
-            | (:? vector as a) -> DS.inplaceCptMulVecDS   a (tightenV b)
-            | _                -> GU.inplaceCptMulVecGU a b
-
-        let inplaceScaleM a b = 
-            match b with 
-            | DenseRepr b -> 
-                match box b with 
-                | (:? dmatrix as b)  -> DS.inplaceScaleDenseMatrixDS   (tightenF a) b
-                | _                 -> GU.inplaceScaleDenseMatrixGU a b
-            | _ -> sparseNotMutable()
-
-        let inplaceScaleV a b = 
-            match box b with 
-            | (:? vector as b)  -> DS.inplaceScaleVecDS   (tightenF a) b
-            | _                 -> GU.inplaceScaleVecGU a b
-
-        let existsM  f a = 
-            match a with 
-            | SparseRepr _ -> sparseNYI() // note: martin says "run f on a token element if it's not full"
-            | DenseRepr a -> GU.existsiDenseMatrixGU  (fun _ _ -> f) a
-
-        let existsV  f a = GU.existsiVecGU  (fun _ -> f) a
-
-        let forallM  f a = 
-            match a with 
-            | SparseRepr _ -> sparseNYI()
-            | DenseRepr a -> GU.foralliDenseMatrixGU  (fun _ _ -> f) a
-
-        let forallV  f a = GU.foralliVecGU  (fun _ -> f) a
-
-        let existsiM  f a = 
-            match a with 
-            | SparseRepr _ -> sparseNYI()
-            | DenseRepr a -> GU.existsiDenseMatrixGU  f a
-
-        let existsiV  f a = GU.existsiVecGU  f a
-
-        let foralliM  f a = 
-            match a with 
-            | SparseRepr _ -> sparseNYI()
-            | DenseRepr a -> GU.foralliDenseMatrixGU  f a
-
-        let foralliV  f a = GU.foralliVecGU  f a
-
-        let mapM  f a = 
-            match a with 
-            | SparseRepr _ -> sparseNYI()
-            | DenseRepr a -> DenseRepr(GU.mapDenseMatrixGU f a)
-
-        let mapV  f a = GU.mapVecGU f a
-
-        let copyM  a = 
-            match a with 
-            | SparseRepr a -> SparseRepr (GU.copySparseGU a)
-            | DenseRepr a -> DenseRepr (GU.copyDenseMatrixGU a)
-
-        let copyV  a = GU.copyVecGU a
-
-        let copyRV  a = GU.copyRowVecGU a
-
-        let mapiM  f a = 
-            match a with 
-            | SparseRepr _ -> sparseNYI()
-            | DenseRepr a -> DenseRepr (GU.mapiDenseMatrixGU f a)
-
-        let mapiV  f a = GU.mapiVecGU f a
-        let permuteV p a = GU.permuteVecGU p a
-        let permuteRV p a = GU.permuteRowVecGU p a
-
-        let mapiRV  f a = GU.mapiRowVecGU f a
-
-        let toDenseM a = 
-            match a with 
-            | SparseRepr a -> GU.toDenseSparseMatrixGU a |> dense
-            | DenseRepr _ -> a
-
-        let initSparseM i j x : Matrix<'T> = 
-            let opsData = opsdata<'T> 
-            GU.initSparseMatrixGU i j opsData x |> sparse
-          
-        let initDenseM i j x : Matrix<'T> = 
-            let r = zeroM i j
-            x |> Seq.iter (fun (i,j,v) -> r.[i,j] <- v);
-            r
-
-        let getDiagnM (a:Matrix<_>) n =
-            let nA = a.NumCols 
-            let mA = a.NumRows
-            if nA<>mA then invalidArg "a" "expected a square matrix";
-            let ni = if n < 0 then -n else 0 
-            let nj = if n > 0 then  n else 0 
-            GU.createVecGU (opsM a) (max (nA-abs(n)) 0) (fun i -> a.[i+ni,i+nj]) 
-
-        let getDiagM  a = getDiagnM a 0
-
-        let inline inplace_mapiM  f a = 
-            match a with 
-            | SparseRepr _ -> sparseNotMutable()
-            | DenseRepr a -> GU.inplace_mapiDenseMatrixGU f a
-
-        let inline inplace_mapiV  f a = GU.inplace_mapiVecGU f a
-        
-        let inline foldM  f z a = 
-            match a with 
-            | SparseRepr _ -> sparseNYI()
-            | DenseRepr a -> GU.foldDenseMatrixGU f z a
-
-        let inline foldV  f z a = GU.foldVecGU f z a
-
-        let inline foldiM  f z a = 
-            match a with 
-            | SparseRepr _ -> sparseNYI()
-            | DenseRepr a -> GU.foldiDenseMatrixGU f z a
-
-        let inline foldiV  f z a = GU.foldiVecGU f z a
-
-        let compareM (comp: IComparer) (a:Matrix<'T>) (b:Matrix<'T>) = 
-            let nA = a.NumCols 
-            let mA = a.NumRows 
-            let nB = b.NumCols 
-            let mB = b.NumRows 
-            let c = compare mA mB 
-            if c <> 0 then c else
-            let c = compare nA nB 
-            if c <> 0 then c else
-            match a,b with 
-            | DenseRepr a, DenseRepr b -> 
-              let rec go2 i j = 
-                 if j < nA then 
-                   let c = comp.Compare( a.[i,j], b.[i,j])
-                   if c <> 0 then c else 
-                   go2 i (j+1) 
-                 else 0 
-              let rec go1 i = 
-                 if i < mA then 
-                   let c = go2 i 0 
-                   if c <> 0 then c 
-                   else go1 (i+1) 
-                 else 0 
-              go1 0
-            | _ -> 
-              match (mergedNonZeroEntriesM a b |> Seq.tryPick (fun (v1,v2) -> let c = comp.Compare(v1,v2) in if c = 0 then None else Some(c))) with
-              | None -> 0
-              | Some(c) -> c
-             
-        let equalsM (comp: IEqualityComparer) (a:Matrix<'T>) (b:Matrix<'T>) = 
-            let nA = a.NumCols 
-            let mA = a.NumRows 
-            let nB = b.NumCols 
-            let mB = b.NumRows 
-            (mA = mB ) && (nA = nB) && 
-            match a,b with 
-            | DenseRepr a, DenseRepr b -> 
-                let rec go2 i j =  j >= nA || (comp.Equals( a.[i,j], b.[i,j]) && go2 i (j+1) )
-                let rec go1 i = i >= mA || (go2 i 0  && go1 (i+1))
-                go1 0
-            | _ -> 
-                mergedNonZeroEntriesM a b |> Seq.forall (fun (v1,v2) -> comp.Equals(v1,v2))
-             
-
-        let compareV (comp: IComparer) (a:Vector<'T>) (b:Vector<'T>) = 
-            let mA = a.NumRows
-            let mB = b.NumRows 
-            let c = compare mA mB 
-            if c <> 0 then c else
-            let rec go2 j = 
-               if j < mA then 
-                 let c = comp.Compare(a.[j],b.[j])
-                 if c <> 0 then c else go2 (j+1) 
-               else 0 
-            go2 0
-
-        let equalsV (comp: IEqualityComparer) (a:Vector<'T>) (b:Vector<'T>) = 
-            let mA = a.NumRows
-            let mB = b.NumRows 
-            (mA = mB) && 
-            let rec go2 j = (j >= mA) || (comp.Equals(a.[j],b.[j]) && go2 (j+1))
-            go2 0
-
-        let equalsRV (comp: IEqualityComparer) (a:RowVector<'T>) (b:RowVector<'T>) = 
-            let mA = a.NumCols 
-            let mB = b.NumCols 
-            (mA = mB) && 
-            let rec go2 j = (j >= mA) || (comp.Equals(a.[j],b.[j]) && go2 (j+1))
-            go2 0
-
-        let compareRV (comp: IComparer) (a:RowVector<'T>) (b:RowVector<'T>) = 
-            let mA = a.NumCols 
-            let mB = b.NumCols 
-            let c = compare mA mB 
-            if c <> 0 then c else
-            let rec go2 j = 
-               if j < mA then 
-                 let c = comp.Compare(a.[j],b.[j])
-                 if c <> 0 then c else go2 (j+1) 
-               else 0 
-            go2 0
-
-        let inline combineHash x y = (x <<< 1) + y + 631 
-
-        let hashM (comp:IEqualityComparer) (a:Matrix<_>) = 
-            let nA = a.NumCols 
-            let mA = a.NumRows 
-            let acc = hash mA + hash nA
-            a |> nonZeroEntriesM |> Seq.truncate 20 |> Seq.fold (fun z v -> combineHash z (comp.GetHashCode v)) acc
-          
-        let hashV (comp:IEqualityComparer) (a:Vector<_>) = 
-            let mA = a.NumRows 
-            hash mA +
-            (let mutable c = 0 
-             for i = 0 to mA - 1 do
-                 c <- combineHash c (comp.GetHashCode a.[i])
-             c)
-          
-        let hashRV (comp:IEqualityComparer) (a:RowVector<_>) = 
-            let mA = a.NumCols 
-            hash mA +
-            (let mutable c = 0 
-             for i = 0 to mA - 1 do
-                 c <- combineHash c (comp.GetHashCode a.[i])
-             c)
-          
-        type range = int * int
-
-        let startR ((a,_) : range)   = a
-        let countR ((a,b) : range)   = (b-a)+1
-        let idxR    ((a,_) : range) i = a+i
-        let inR    ((a,b) : range) i = a <= i && i <= b
-        
-        let getRowM  (a:Matrix<_>) i = createRVx (opsM a) a.NumCols (fun j -> a.[i,j])
-        let selColM  (a:Matrix<_>) j = createVx (opsM a) a.NumRows (fun i -> a.[i,j]) 
-        let getRegionV  (a:Vector<_>)    r      = createVx a.OpsData (countR r) (fun i -> a.[idxR r i]) 
-        let getRegionRV (a:RowVector<_>) r      = createRVx a.OpsData (countR r) (fun i -> a.[idxR r i]) 
-
-        let getRegionM  a ri rj    = 
-            match a with 
-            | DenseRepr a -> createMx a.OpsData (countR ri) (countR rj) (fun i j -> a.[idxR ri i, idxR rj j]) 
-            | _ -> nonZeroEntriesM a 
-                   |> Seq.filter (fun (i,j,_) -> inR ri i && inR rj j) 
-                   |> Seq.map (fun (i,j,v) -> (i-startR ri,j-startR rj,v)) 
-                   |> initSparseM (countR ri) (countR rj)
-
-        let getColsM (a:Matrix<_>) rj         = getRegionM a (0,a.NumRows - 1) rj
-        let getRowsM (a:Matrix<_>) ri         = getRegionM a ri (0,a.NumCols - 1)
-
-        let rowvecM (x:RowVector<_>) = initM 1         x.NumCols (fun _ j -> x.[j]) 
-        let vectorM (x:Vector<_>) = initM x.NumRows  1         (fun i _ -> x.[i])  
-        let toVectorM x = selColM x 0 
-        let toRowVectorM x = getRowM x 0 
-        let toScalarM (x:Matrix<_>) = x.[0,0]
-
-
-
-//----------------------------------------------------------------------------
-// type Matrix<'T> augmentation
-//--------------------------------------------------------------------------*)
-
-    type Matrix<'T> with
-        static member ( +  )(a: Matrix<'T>,b) = SpecializedGenericImpl.addM a b
-        static member ( -  )(a: Matrix<'T>,b) = SpecializedGenericImpl.subM a b
-        static member ( *  )(a: Matrix<'T>,b) = SpecializedGenericImpl.mulM a b
-        static member ( *  )(a: Matrix<'T>,b : Vector<'T>) = SpecializedGenericImpl.mulMV a b
-
-        static member ( * )((m: Matrix<'T>),k : 'T) = SpecializedGenericImpl.scaleM k m
-
-        static member ( .* )(a: Matrix<'T>,b) = SpecializedGenericImpl.cptMulM a b
-        static member ( * )(k,m: Matrix<'T>) = SpecializedGenericImpl.scaleM k m
-        static member ( ~- )(m: Matrix<'T>)     = SpecializedGenericImpl.negM m
-        static member ( ~+ )(m: Matrix<'T>)     = m
-
-        member m.GetSlice (start1,finish1,start2,finish2) = 
-            let start1 = match start1 with None -> 0 | Some v -> v 
-            let finish1 = match finish1 with None -> m.NumRows - 1 | Some v -> v 
-            let start2 = match start2 with None -> 0 | Some v -> v 
-            let finish2 = match finish2 with None -> m.NumCols - 1 | Some v -> v 
-            SpecializedGenericImpl.getRegionM m (start1,finish1) (start2,finish2)
-
-        member m.SetSlice (start1,finish1,start2,finish2,vs:Matrix<_>) = 
-            let start1 = match start1 with None -> 0 | Some v -> v 
-            let finish1 = match finish1 with None -> m.NumRows - 1 | Some v -> v 
-            let start2 = match start2 with None -> 0 | Some v -> v 
-            let finish2 = match finish2 with None -> m.NumCols - 1 | Some v -> v 
-            for i = start1 to finish1  do 
-               for j = start2 to finish2 do
-                   m.[i,j] <- vs.[i-start1,j-start2]
-
-        override m.ToString() = 
-           match m with 
-           | DenseRepr m -> GenericImpl.showDenseMatrixGU m
-           | SparseRepr _ -> "<sparse>"
-
-        member m.DebugDisplay = 
-           let txt = 
-               match m with 
-               | DenseRepr m -> GenericImpl.debugShowDenseMatrixGU m
-               | SparseRepr _ -> "<sparse>"
-           new System.Text.StringBuilder(txt)  // return an object with a ToString with the right value, rather than a string. (strings get shown using quotes)
-
-        member m.StructuredDisplayAsArray =  
-            let rec layout m = 
-                match m with 
-                | DenseRepr _ -> box (Array2D.init m.NumRows m.NumCols (fun i j -> m.[i,j]))
-                | SparseRepr _ -> (if m.NumRows < 20 && m.NumCols < 20 then layout (SpecializedGenericImpl.toDenseM m) else box(SpecializedGenericImpl.nonZeroEntriesM m))
-            layout m
-        member m.Dimensions = m.NumRows,m.NumCols
-
-        member m.Transpose = SpecializedGenericImpl.transM m
-        member m.PermuteRows (p: permutation) : Matrix<'T> = SpecializedGenericImpl.permuteRows p m
-        member m.PermuteColumns (p: permutation) : Matrix<'T> = SpecializedGenericImpl.permuteColumns p m
-
-        interface IEnumerable<'T> with 
-            member m.GetEnumerator() = 
-               (seq { for i in 0 .. m.NumRows-1 do
-                        for j in 0 .. m.NumCols - 1 do 
-                            yield m.[i,j] }).GetEnumerator()
-
-        interface IEnumerable with 
-            member m.GetEnumerator() =  ((m :> IEnumerable<_>).GetEnumerator() :> IEnumerator)
-                                    
-        interface System.IComparable with 
-             member m.CompareTo(yobj:obj) = SpecializedGenericImpl.compareM LanguagePrimitives.GenericComparer m (yobj :?> Matrix<'T>)
-             
-        interface IStructuralComparable with
-            member m.CompareTo(yobj:obj,comp:System.Collections.IComparer) = SpecializedGenericImpl.compareM comp m (yobj :?> Matrix<'T>)
-            
-        override m.GetHashCode() = SpecializedGenericImpl.hashM LanguagePrimitives.GenericEqualityComparer m 
-        override m.Equals(yobj:obj) = 
-            match yobj with 
-            | :? Matrix<'T> as m2 -> SpecializedGenericImpl.equalsM LanguagePrimitives.GenericEqualityComparer m m2
-            | _ -> false
-        
-        interface IStructuralEquatable with
-            member m.GetHashCode(comp:System.Collections.IEqualityComparer) = SpecializedGenericImpl.hashM comp m
-            member m.Equals(yobj:obj,comp:System.Collections.IEqualityComparer) = 
-                match yobj with 
-                | :? Matrix<'T> as m2 -> SpecializedGenericImpl.equalsM comp m m2
-                | _ -> false
-
-
-//----------------------------------------------------------------------------
-// type Vector<'T> augmentation
-//--------------------------------------------------------------------------*)
-
-    type Vector<'T> with
-        static member ( +  )(a: Vector<'T>,b) = SpecializedGenericImpl.addV a b
-        static member ( -  )(a: Vector<'T>,b) = SpecializedGenericImpl.subV a b
-        static member ( .* )(a: Vector<'T>,b) = SpecializedGenericImpl.cptMulV a b
-        
-        static member ( * )(k,m: Vector<'T>) = SpecializedGenericImpl.scaleV k m
-        
-        static member ( * )(a: Vector<'T>,b) = SpecializedGenericImpl.mulVRV a b
-        
-        static member ( * )(m: Vector<'T>,k) = SpecializedGenericImpl.scaleV k m
-        
-        static member ( ~- )(m: Vector<'T>)     = SpecializedGenericImpl.negV m
-        static member ( ~+ )(m: Vector<'T>)     = m
-
-        member m.GetSlice (start,finish) = 
-            let start = match start with None -> 0 | Some v -> v 
-            let finish = match finish with None -> m.NumRows - 1 | Some v -> v 
-            SpecializedGenericImpl.getRegionV m (start,finish)
-
-        member m.SetSlice (start,finish,vs:Vector<_>) = 
-            let start = match start with None -> 0 | Some v -> v 
-            let finish = match finish with None -> m.NumRows - 1 | Some v -> v 
-            for i = start to finish  do 
-                   m.[i] <- vs.[i-start]
-
-
-        override m.ToString() = GenericImpl.showVecGU "vector" m
-
-        member m.DebugDisplay = 
-            let txt = GenericImpl.showVecGU "vector" m
-            new System.Text.StringBuilder(txt)  // return an object with a ToString with the right value, rather than a string. (strings get shown using quotes)
-
-        member m.StructuredDisplayAsArray =  Array.init m.NumRows (fun i -> m.[i])
-
-        member m.Details = m.Values
-
-        member m.Transpose = SpecializedGenericImpl.transV m
-        
-        member m.Permute (p:permutation) = SpecializedGenericImpl.permuteV p m
-      
-        interface System.IComparable with 
-             member m.CompareTo(y:obj) = SpecializedGenericImpl.compareV LanguagePrimitives.GenericComparer m (y :?> Vector<'T>)
-        
-        interface IStructuralComparable with
-            member m.CompareTo(y:obj,comp:System.Collections.IComparer) = SpecializedGenericImpl.compareV comp m (y :?> Vector<'T>)
-
-        interface IStructuralEquatable with
-            member x.GetHashCode(comp) = SpecializedGenericImpl.hashV comp x
-            member x.Equals(yobj,comp) = 
-                match yobj with 
-                | :? Vector<'T> as v2 -> SpecializedGenericImpl.equalsV comp x v2
-                | _ -> false
-
-        override x.GetHashCode() = 
-            SpecializedGenericImpl.hashV LanguagePrimitives.GenericEqualityComparer x
-
-        override x.Equals(yobj) = 
-            match yobj with 
-            | :? Vector<'T> as v2 -> SpecializedGenericImpl.equalsV LanguagePrimitives.GenericEqualityComparer x v2
-            | _ -> false
-
-//----------------------------------------------------------------------------
-// type RowVector<'T> augmentation
-//--------------------------------------------------------------------------*)
-
-    type RowVector<'T> with
-        static member ( +  )(a: RowVector<'T>,b) = SpecializedGenericImpl.addRV a b
-        static member ( -  )(a: RowVector<'T>,b) = SpecializedGenericImpl.subRV a b
-        static member ( .* )(a: RowVector<'T>,b) = SpecializedGenericImpl.cptMulRV a b
-        static member ( * )(k,v: RowVector<'T>) = SpecializedGenericImpl.scaleRV k v
-        
-        static member ( * )(a: RowVector<'T>,b: Matrix<'T>) = SpecializedGenericImpl.mulRVM a b
-        static member ( * )(a: RowVector<'T>,b:Vector<'T>) = SpecializedGenericImpl.mulRVV a b
-        static member ( * )(v: RowVector<'T>,k:'T) = SpecializedGenericImpl.scaleRV k v
-        
-        static member ( ~- )(v: RowVector<'T>)     = SpecializedGenericImpl.negRV v
-        static member ( ~+ )(v: RowVector<'T>)     = v
-
-        member m.GetSlice (start,finish) = 
-            let start = match start with None -> 0 | Some v -> v
-            let finish = match finish with None -> m.NumCols - 1 | Some v -> v 
-            SpecializedGenericImpl.getRegionRV m (start,finish)
-
-        member m.SetSlice (start,finish,vs:RowVector<_>) = 
-            let start = match start with None -> 0 | Some v -> v 
-            let finish = match finish with None -> m.NumCols - 1 | Some v -> v 
-            for i = start to finish  do 
-                   m.[i] <- vs.[i-start]
-
-        override m.ToString() = GenericImpl.showRowVecGU "rowvec" m
-
-        member m.DebugDisplay = 
-            let txt = GenericImpl.showRowVecGU "rowvec" m
-            new System.Text.StringBuilder(txt)  // return an object with a ToString with the right value, rather than a string. (strings get shown using quotes)
-
-        member m.StructuredDisplayAsArray =  Array.init m.NumCols (fun i -> m.[i])
-
-        member m.Details = m.Values
-
-        member m.Transpose = SpecializedGenericImpl.transRV m
-        
-        member m.Permute (p:permutation) = SpecializedGenericImpl.permuteRV p m
-      
-        interface System.IComparable with 
-            member m.CompareTo(y) = SpecializedGenericImpl.compareRV LanguagePrimitives.GenericComparer m (y :?> RowVector<'T>)
-        
-        interface IStructuralComparable with
-            member m.CompareTo(y,comp) = SpecializedGenericImpl.compareRV comp m (y :?> RowVector<'T>)
-
-        interface IStructuralEquatable with
-            member x.GetHashCode(comp) = SpecializedGenericImpl.hashRV comp x
-            member x.Equals(yobj,comp) = 
-                match yobj with 
-                | :? RowVector<'T> as rv2 -> SpecializedGenericImpl.equalsRV comp x rv2
-                | _ -> false
-
-        override x.GetHashCode() = 
-            SpecializedGenericImpl.hashRV LanguagePrimitives.GenericEqualityComparer x
-
-        override x.Equals(yobj) = 
-            match yobj with 
-            | :? RowVector<'T> as rv2 -> SpecializedGenericImpl.equalsRV LanguagePrimitives.GenericEqualityComparer x rv2
-            | _ -> false
-
-    type matrix = Matrix<float>
-    type vector = Vector<float>
-    type rowvec = RowVector<float>
-
-    module MRandom = 
-        let seed = 99
-        let randomGen = new System.Random(seed)
-        let float f = randomGen.NextDouble() * f 
-
-
-    [<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
-    module Matrix = begin
-        
-        module Generic = begin
-
-            module MS = SpecializedGenericImpl
-
-            // Accessors
-            let get (a:Matrix<_>) i j   = a.[i,j]
-            let set (a:Matrix<_>) i j x = a.[i,j] <- x
-            
-            // Creation
-            let ofList    xss      = MS.listM  xss
-            let ofSeq     xss      = MS.seqM  xss
-            let init  m n f       = MS.initM  m n f
-            let ofArray2D (arr: 'T[,])  : Matrix<'T>       = MS.arrayM arr
-            let toArray2D (m:Matrix<_>) = Array2D.init m.NumRows m.NumCols (fun i j -> get m i j)
-            let initNumeric m n f = MS.initNumericM m n f
-            let zero m n            = MS.zeroM m n
-            let identity m          = MS.identityM m
-            let create  m n x       = MS.constM m n x
-
-            let ofScalar   x        = MS.scalarM x
-
-            let diag v              = MS.diagM v
-            let initDiagonal v      = MS.diagM v
-            let constDiag   n x     = MS.constDiagM n x
-          
-            // Operators
-            let add a b = MS.addM a b
-            let sub a b = MS.subM a b
-            let mul a b = MS.mulM a b
-            let mulRV a b = MS.mulRVM a b
-            let mulV a b = MS.mulMV a b
-            let cptMul a b = MS.cptMulM a b
-            let cptMax a b = MS.cptMaxM a b
-            let cptMin a b = MS.cptMinM a b
-            let scale a b = MS.scaleM a b
-            let dot a b = MS.dotM a b
-            let neg a = MS.negM a 
-            let trace a = MS.traceM a
-            let sum a = MS.sumM a
-            let prod a = MS.prodM a
-            let norm a = MS.normM a
-            let transpose a = MS.transM a
-            let inplaceAdd a b = MS.inplaceAddM a b
-            let inplaceSub a b = MS.inplaceSubM a b
-
-            let exists  f a = MS.existsM  f a
-            let forall  f a = MS.forallM  f a
-            let existsi  f a = MS.existsiM  f a
-            let foralli  f a = MS.foralliM  f a
-            let map  f a = MS.mapM f a
-            let copy a = MS.copyM a
-            let mapi  f a = MS.mapiM f a
-            let getDiagN  a n = MS.getDiagnM a n
-            let getDiag  a = MS.getDiagnM a 0
-            let toDense a = MS.toDenseM a 
-
-            let initDense i j a = MS.initDenseM i j a 
-            let initSparse i j a = MS.initSparseM i j a 
-
-            let fold  f z a = MS.foldM f z a
-            let foldi f z a = MS.foldiM f z a
-          
-            let compare a b = MS.compareM LanguagePrimitives.GenericComparer a b
-            let hash a      = MS.hashM LanguagePrimitives.GenericEqualityComparer a
-            let getRow    a i           = MS.getRowM a i
-            let getCol    a j           = MS.selColM a j
-            let getCols   a i1 i2       = MS.getColsM a (i1,i1+i2-1)
-            let getRows   a j1 j2       = MS.getRowsM a (j1,j1+j2-1)
-            let getRegion a i1 j1 i2 j2 = MS.getRegionM a (i1,i1+i2-1) (j1,j1+j2-1)
-            
-            let ofRowVector x = MS.rowvecM x
-            let ofVector    x = MS.vectorM x
-            let toVector    x = MS.toVectorM x
-            let toRowVector x = MS.toRowVectorM x
-            let toScalar    x = MS.toScalarM x
-
-            let inplace_assign f a  = MS.inplaceAssignM  f a
-            let inplace_cptMul a b = MS.inplaceCptMulM a b
-            let inplace_scale a b = MS.inplaceScaleM a b
-            let inplace_mapi  f a = MS.inplace_mapiM f a
-            let of_rowvec x           = ofRowVector x
-            let of_vector x           = ofVector x
-            let to_vector x           = toVector x
-            let to_rowvec x           = toRowVector x
-            let to_scalar x           = toScalar x
-            let inplace_add a b       = inplaceAdd a b
-            let inplace_sub a b       = inplaceSub a b
-            let of_scalar   x         = ofScalar x
-            let of_list    xss        = ofList xss
-            let of_seq     xss        = ofSeq xss
-            let inline of_array2D arr = ofArray2D arr
-            let inline to_array2D m   = toArray2D m
-            let init_diagonal v       = initDiagonal v
-            let to_dense a            = toDense a
-            let init_dense i j a      = initDense i j a
-            let init_sparse i j a     = initSparse i j a
-            let nonzero_entries a     = MS.nonZeroEntriesM a 
-         
-        end
-
-        module MG = Generic
-        module DS = DoubleImpl
-        module GU = GenericImpl
-        module MS = SpecializedGenericImpl
-
-        // Element type OpsData
-        type elem = float
-
-        // Accessors
-        let get (a:matrix) i j   = MG.get a i j
-        let set (a:matrix) i j x = MG.set a i j x
-        
-        // Creation
-        let init  m n f = DS.initDenseMatrixDS  m n f |> MS.dense 
-        let ofList    xss   = DS.listDenseMatrixDS    xss |> MS.dense
-        let ofSeq     xss   = DS.seqDenseMatrixDS    xss |> MS.dense
-        let diag  (v:vector)   = MG.diag v 
-        let initDiagonal  (v:vector)   = MG.diag v 
-        let constDiag  n x : matrix  = MG.constDiag n x 
-        let create  m n x  = DS.constDenseMatrixDS  m n x |> MS.dense
-        let ofScalar x     = DS.scalarDenseMatrixDS x |> MS.dense
-
-        let ofArray2D arr : matrix = MG.ofArray2D arr
-        let toArray2D (m : matrix) = MG.toArray2D m
-
-        let getDiagN  (a:matrix) n = MG.getDiagN a n
-        let getDiag  (a:matrix) = MG.getDiag a
-
-        // Operators
-        let add (a:matrix) (b:matrix) = MS.addM   a b
-        let sub (a:matrix) (b:matrix) = MS.subM   a b
-        let mul (a:matrix) (b:matrix) = MS.mulM   a b
-        let mulV (a:matrix) (b:vector) = MS.mulMV   a b
-        let mulRV (a:rowvec) (b:matrix) = MS.mulRVM   a b
-        let cptMul (a:matrix) (b:matrix) = MS.cptMulM   a b
-        let cptMax (a:matrix) (b:matrix) = MS.cptMaxM a b
-        let cptMin (a:matrix) (b:matrix) = MS.cptMinM a b
-        let scale a (b:matrix) = MS.scaleM   a b
-        let neg (a:matrix)  = MS.negM a
-        let trace (a:matrix)  = MS.traceM a
-        let transpose  (a:matrix) = MG.transpose a
-        let forall f (a:matrix) = MG.forall f a
-        let exists  f (a:matrix) = MG.exists f a
-        let foralli f (a:matrix) = MG.foralli f a
-        let existsi  f (a:matrix) = MG.existsi f a
-        let map  f (a:matrix) = MG.map f a
-        let copy  (a:matrix) = MG.copy a
-        let mapi  f (a:matrix) : matrix = MG.mapi f a
-        let fold  f z (a:matrix) = MG.fold f z a
-        let foldi  f z (a:matrix) = MG.foldi f z a
-
-        let toDense (a:matrix) = MG.toDense a 
-        let initDense i j a : matrix = MG.initDense i j a 
-        let initSparse i j a : matrix = MG.initSparse i j a 
-        let nonzero_entries (a:matrix) = MG.nonzero_entries a 
-
-        let zero m n  = DS.zeroDenseMatrixDS m n |> MS.dense
-        let identity m  : matrix = MG.identity m 
-        
-        let ones m n  = create m n 1.0
-        
-        let getRow (a:matrix) i      = MG.getRow a i
-        let getCol (a:matrix) j      = MG.getCol a j
-        let getCols (a:matrix) i1 i2    = MG.getCols a i1 i2
-        let getRows (a:matrix) j1 j2    = MG.getRows a j1 j2
-        let getRegion (a:matrix) i1 j1 i2 j2    = MG.getRegion a i1 j1 i2 j2
-
-        let rowRange (a:Matrix<_>) = (0,a.NumRows - 1)
-        let colRange (a:Matrix<_>) = (0,a.NumCols - 1)
-        let wholeRegion a = (colRange a, rowRange a)
-        
-        let foldByRow f (z:Vector<'T>) (a:matrix) = 
-          colRange a |> GU.foldR (fun z j -> MS.mapiV (fun i z -> f z (get a i j)) z) z
-        let foldByCol f (z:RowVector<'T>) (a:matrix) = 
-          rowRange a |> GU.foldR (fun z i -> MS.mapiRV (fun j z -> f z (get a i j)) z) z
-
-        let foldRow f (z:'T) (a:matrix) i = 
-          colRange a |> GU.foldR (fun (z:'T) j -> f z (get a i j)) z
-        let foldCol f (z:'T) (a:matrix) j = 
-          rowRange a |> GU.foldR (fun (z:'T) i -> f z (get a i j)) z
-
-        let sum (a:matrix)  = MS.sumM a
-        let prod (a:matrix)  = MS.prodM a
-        let norm  (a:matrix) = MS.normM  a
-        let dot (a:matrix) b = MS.dotM a b
-
-        let cptPow  a y = map (fun x -> x ** y) a
-        
-        // Functions that only make sense on this type
-        let randomize v = map (fun vij -> MRandom.float vij) v      (* res_ij = random [0,vij] values *)
-
-        let ofRowVector x : matrix = MS.rowvecM x
-        let ofVector    x : matrix = MS.vectorM x
-        let toVector    x : vector = MS.toVectorM x
-        let toRowVector x : rowvec = MS.toRowVectorM x
-        let toScalar    x : float  = MS.toScalarM x
-
-        let inplaceAdd  (a:matrix) b = MS.inplaceAddM a b
-        let inplaceSub  (a:matrix) b = MS.inplaceSubM a b
-
-        // Mutation
-        let inplace_assign  f (a:matrix) = MG.inplace_assign f a
-        let inplace_mapi  f (a:matrix) = MG.inplace_mapi f a
-        let inplace_cptMul (a:matrix) b = MS.inplaceCptMulM a b
-        let inplace_scale  a (b:matrix) = MS.inplaceScaleM a b
-
-        let inplace_add  a b = inplaceAdd a b
-        let inplace_sub  a b = inplaceSub a b
-        let of_rowvec x = ofRowVector x
-        let of_vector x = ofVector x
-        let to_vector x = toVector x
-        let to_rowvec x = toRowVector x
-        let to_scalar x = toScalar x
-        let inline of_array2D arr  = ofArray2D arr
-        let inline to_array2D m = toArray2D m
-        let of_list    xss   = ofList xss
-        let of_seq     xss   = ofSeq xss
-        let init_diagonal v   = initDiagonal   v
-        let of_scalar x     = ofScalar x
-        let to_dense x = toDense x
-        let init_dense i j a = initDense i j a
-        let init_sparse i j a = initSparse i j a
-
-
-    end
-
-
-//----------------------------------------------------------------------------
-// module Vector
-//--------------------------------------------------------------------------*)
-      
-    [<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
-    module Vector = 
-
-        module Generic = 
-
-            module OpsS = SpecializedGenericImpl
-
-            let get (a:Vector<_>) i   = a.[i]
-            let set (a:Vector<_>) i x = a.[i] <- x
-            let length (v:Vector<_>) = v.Length
-            let ofList    xss   = OpsS.listV xss
-            let ofSeq    xss   = OpsS.seqV xss
-            let init  m   f = OpsS.initV m f
-            let initNumeric  m   f = OpsS.createNumericV m f
-            let ofArray arr       = OpsS.arrayV arr
-            let toArray (v:Vector<_>) = Array.init v.Length (get v)
-
-            let create  m x   = OpsS.constV m x
-            let zero n = OpsS.zeroV n
-            let ones n = OpsS.createNumericV n (fun ops _ -> ops.One)
-            let ofScalar   x = OpsS.scalarV x
-            let add a b = OpsS.addV a b
-            let sub a b = OpsS.subV a b
-            let mulRVV a b = OpsS.mulRVV a b
-            let mulVRV a b = OpsS.mulVRV a b
-            let cptMul a b = OpsS.cptMulV a b
-            let cptMax a b = OpsS.cptMaxV a b
-            let cptMin a b = OpsS.cptMinV a b
-            let scale a b = OpsS.scaleV a b
-            let dot a b = OpsS.dotV a b
-            let neg a = OpsS.negV a 
-            let transpose a = OpsS.transV a 
-            let inplaceAdd a b = OpsS.inplaceAddV a b
-            let inplaceSub a b = OpsS.inplaceSubV a b
-            let inplace_cptMul a b = OpsS.inplaceCptMulV a b
-            let inplace_scale a b = OpsS.inplaceScaleV a b
-
-
-
-            let exists  f a = OpsS.existsV  f a
-            let forall  f a = OpsS.forallV  f a
-            let existsi  f a = OpsS.existsiV  f a
-            let foralli  f a = OpsS.foralliV  f a
-            let map  f a = OpsS.mapV f a
-            let mapi f a = OpsS.mapiV f a
-            let copy a = OpsS.copyV a
-            let inplace_mapi  f a = OpsS.inplace_mapiV f a
-            let fold  f z a = OpsS.foldV f z a
-            let foldi  f z a = OpsS.foldiV f z a
-            let compare a b = OpsS.compareV a b
-            let hash a = OpsS.hashV a
-            let inplace_assign  f a = OpsS.assignV f a
-            let sum  (a:Vector<_>) = let ops = a.ElementOps in fold (fun x y -> ops.Add(x,y)) ops.Zero a
-            let prod (a:Vector<_>) = let ops = a.ElementOps in fold (fun x y -> ops.Multiply(x,y)) ops.One a
-            let norm (a:Vector<_>) = 
-                let normOps = GenericImpl.getNormOps a.ElementOps 
-                sqrt (fold (fun x y -> x + normOps.Norm(y)**2.0) 0.0 a)
-
-            let of_list    xss  = ofList xss
-            let of_seq    xss   = ofSeq xss
-            let of_array arr    = ofArray arr
-            let to_array v      = toArray v
-            let of_scalar   x   = ofScalar x
-            let inplace_add a b = inplaceAdd a b
-            let inplace_sub a b = inplaceSub a b
-
-        module VG = Generic
-        module VecDS = DoubleImpl
-        module VecGU = GenericImpl
-
-        let get (a:vector) j   = VG.get a j 
-        let set (a:vector) j x = VG.set a j x
-        let length (a:vector)     = VG.length a
-        let nrows (a:vector)   = VG.length a
-        let init  m   f = VecDS.createVecDS  m   f
-        let ofArray arr : vector = VG.ofArray arr
-        let toArray (m : vector) = VG.toArray m
-
-        type range = int * int
-        let countR ((a,b) : range)   = (b-a)+1
-        let idxR    ((a,_) : range) i = a+i
-        type rangef = float * float * float // start, skip, end
-        let countRF ((a,d,b) : rangef)   = System.Convert.ToInt32((b-a)/d) + 1
-        //let countRF ((a,d,b) : rangef)   = Float.to_int((b-a)/d) + 1
-        let idxRF  ((a,d,b) : rangef) i = System.Math.Min (a + d * float(i),b)
-
-        let range n1 n2    = let r = (n1,n2)   in init (countR  r) (fun i -> float(idxR r i)) 
-
-        let rangef a b c  = let r = (a,b,c) in init (countRF r) (fun i -> idxRF r i)
-
-        let ofList    xs    = VecDS.listVecDS    xs
-        let ofSeq    xs    = VecDS.seqVecDS    xs
-        let create  m   x  = VecDS.constVecDS  m   x
-        let ofScalar x     = VecDS.scalarVecDS x
-        let add a b = VecDS.addVecDS   a b
-        let sub a b = VecDS.subVecDS   a b
-        let mulRVV a b = VecDS.mulRowVecVecDS   a b
-        let mulVRV a b = VecDS.mulVecRowVecDS   a b 
-        let cptMul a b = VecDS.cptMulVecDS   a b
-        let cptMax a b = VecDS.cptMaxVecDS a b
-        let cptMin a b = VecDS.cptMinVecDS a b
-        let scale a b = VecDS.scaleVecDS   a b
-        let neg a  = VecDS.negVecDS a
-        let dot a b = VecDS.dotVecDS a b
-        let transpose  (a:vector) = VG.transpose a
-        let exists  f (a:vector) = VG.exists f a
-        let forall  f (a:vector) = VG.forall f a
-        let existsi  f (a:vector) = VG.existsi f a
-        let foralli  f (a:vector) = VG.foralli f a
-        let map  f (a:vector) = VG.map f a
-        let copy (a:vector) = VG.copy a
-        let mapi  f (a:vector) : vector = VG.mapi f a
-        let fold  f z (a:vector) = VG.fold f z a
-        let foldi  f z (a:vector) = VG.foldi f z a
-        let zero n = create n 0.0
-        let ones n = create n 1.0
-        let sum a  = VecDS.sumVecDS a
-        let prod a   = fold      (fun x y -> x * y) 1.0 a
-        let norm  (a:vector) = sqrt (fold (fun x y -> x + y * y) 0.0 a) (* fixed *)
-        let cptPow  a y = map  (fun x -> x ** y) a
-        let inplace_assign  f (a:vector) = VG.inplace_assign f a
-        let inplace_mapi f (a:vector) = VG.inplace_mapi f a
-        let inplace_add a b = VecDS.inplaceAddVecDS a b
-        let inplace_sub a b = VecDS.inplaceSubVecDS a b
-        let inplace_cptMul a b = VecDS.inplaceCptMulVecDS a b
-        let inplace_scale a b = VecDS.inplaceScaleVecDS a b  
-
-        let of_array arr   = ofArray arr
-        let to_array m     = toArray m
-        let of_list    xs  = ofList xs
-        let of_seq    xs   = ofSeq xs
-        let of_scalar x    = ofScalar x
-
-
-
-//----------------------------------------------------------------------------
-// module RowVector
-//--------------------------------------------------------------------------*)
-
-    [<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
-    module RowVector = 
-
-        module Generic = 
-
-            module OpsS = SpecializedGenericImpl
-
-            let get (a:RowVector<_>) i          = a.[i]
-            let set (a:RowVector<_>) i x        = a.[i] <- x
-            let zero n           = OpsS.zeroRV n
-            let length (v:RowVector<_>) = v.Length
-            let init m   f       = OpsS.initRV m   f
-            let create  m x      = OpsS.constRV m x
-            let transpose a      = OpsS.transRV a
-            let copy a           = OpsS.copyRV a
-            let ofList a         = OpsS.listRV a
-            let ofArray a        = OpsS.arrayRV a
-            let ofSeq a          = OpsS.seqRV a
-            let toArray m        = Array.init (length m) (get m)
-
-            let of_list a        = ofList a
-            let of_array a       = ofArray a
-            let of_seq a         = ofSeq a
-            let to_array m       = toArray m
-
-
-        module RVG = Generic
-
-        let get (a:rowvec) i   = RVG.get a i 
-        let set (a:rowvec) i x = RVG.set a i x
-        let length (a:rowvec)  = RVG.length a
-        let ncols (a:rowvec)   = RVG.length a
-        let ofArray arr : rowvec = RVG.ofArray arr
-        let toArray (m : rowvec) = RVG.toArray m
-        
-        let init m   f : rowvec      = RVG.init m   f
-        let create m   f : rowvec    = RVG.create m   f
-        let zero n = create n 0.0
-        let ofList x : rowvec       = RVG.ofList x
-        let ofSeq x : rowvec       = RVG.ofSeq x
-        let transpose x : vector     = RVG.transpose x
-        let copy x : rowvec          = RVG.copy x
-
-        let of_list x    = ofList x
-        let of_seq x     = ofSeq x
-        let of_array arr = ofArray arr
-        let to_array m   = toArray m
-
-
-    type Matrix<'T> with 
-        member x.ToArray2()        = Matrix.Generic.toArray2D x
-        member x.ToArray2D()        = Matrix.Generic.toArray2D x
-
-#if FX_NO_DEBUG_DISPLAYS
-#else
-        [<DebuggerBrowsable(DebuggerBrowsableState.Collapsed)>]
-#endif
-
-        member x.NonZeroEntries    = Matrix.Generic.nonzero_entries x
-        member x.ToScalar()        = Matrix.Generic.toScalar x
-        member x.ToRowVector()     = Matrix.Generic.toRowVector x               
-        member x.ToVector()        = Matrix.Generic.toVector x
-
-#if FX_NO_DEBUG_DISPLAYS
-#else
-        [<DebuggerBrowsable(DebuggerBrowsableState.Collapsed)>]
-#endif
-        member x.Norm              = Matrix.Generic.norm x
-
-        member x.Column(n)         = Matrix.Generic.getCol x n
-        member x.Row(n)            = Matrix.Generic.getRow x n
-        member x.Columns (i,ni)    = Matrix.Generic.getCols x i ni
-        member x.Rows (j,nj)       = Matrix.Generic.getRows x j nj
-        member x.Region(i,j,ni,nj) = Matrix.Generic.getRegion x i j ni nj
-        member x.GetDiagonal(i)    = Matrix.Generic.getDiagN x i
-
-#if FX_NO_DEBUG_DISPLAYS
-#else
-        [<DebuggerBrowsable(DebuggerBrowsableState.Collapsed)>]
-#endif
-        member x.Diagonal          = Matrix.Generic.getDiag x
-
-        member x.Copy () = Matrix.Generic.copy x
-
-
-    type Vector<'T> with 
-        member x.ToArray() = Vector.Generic.toArray x
-        member x.Norm      = Vector.Generic.norm x
-        member x.Copy ()   = Vector.Generic.copy x
-
-
-    type RowVector<'T> with 
-        member x.ToArray() = RowVector.Generic.toArray x
-        member x.Copy ()   = RowVector.Generic.copy x
-
-
-    module MatrixTopLevelOperators = 
-
-        let matrix ll = Matrix.ofSeq ll
-        let vector l  = Vector.ofSeq  l
-        let rowvec l  = RowVector.ofSeq l
-
+// (c) Microsoft Corporation 2005-2009. 
+
+//----------------------------------------------------------------------------
+// An implementation of generic dense and sparse matrix types.
+//
+// Overview and suffix documentation
+//    _GU  = generic unspecialized (Matrix<T>, Vector<T> etc.) 
+//    _GUA = generic unspecialized op on (underlying) array
+//    _DS  = Double specialized (Matrix<float> = matrix, Vector<float> = vector etc.)
+//
+//    DM   = dense matrix
+//    SM   = sparse matrix
+//    V    = vector (dense)
+//    RV   = row vector (dense)
+
+
+namespace Microsoft.FSharp.Math
+
+    #nowarn "60" // implementations in augmentations
+    #nowarn "69" // implementations in augmentations
+
+    open Microsoft.FSharp.Math
+    open System
+    open System.Globalization
+    open System.Collections
+    open System.Collections.Generic
+    open System.Diagnostics
+    type permutation = int -> int
+
+
+//=========================================================================
+// (c) Microsoft Corporation 2005-2009. 
+//=========================================================================
+
+    [<AutoOpen>]
+    module Helpers = 
+        let sparseNYI() = failwith "this operation is not supported on sparse matrices"
+        let sparseNotMutable() = failwith "sparse matrices are not mutable"
+        
+        [<RequiresExplicitTypeArguments>]
+        let opsdata<'T> = GlobalAssociations.TryGetNumericAssociation<'T>()
+        
+        [<Literal>]
+        let DenseMaxDisplay = 50
+        [<Literal>]
+        let VectorMaxDisplay = 100
+    
+    
+    /// The value stored for the dictionary of numeric operations. If none is present then this indicates
+    /// no operations are known for this type.
+    type OpsData<'T> = INumeric<'T> option
+
+    type DenseMatrix<'T>(opsData : OpsData<'T>, values : 'T[,]) = 
+        member m.OpsData =  opsData
+        member m.Values =  values
+        member m.NumRows = values.GetLength(0)
+        member m.NumCols = values.GetLength(1)
+
+        member m.ElementOps = 
+            match opsData with 
+            | None -> raise (new System.NotSupportedException("The element type carried by this matrix does not support numeric operations"))
+            | Some a -> a
+
+        member m.Item
+           with get (i,j) = values.[i,j]
+           and  set (i,j) x = values.[i,j] <- x
+
+
+
+    type SparseMatrix<'T>(opsData : OpsData<'T>, sparseValues : 'T array, sparseRowOffsets : int array, ncols:int, columnValues: int array) = 
+        member m.OpsData = opsData; 
+        member m.NumCols = ncols
+        member m.NumRows = sparseRowOffsets.Length - 1
+        member m.SparseColumnValues = columnValues
+        member m.SparseRowOffsets =  sparseRowOffsets (* nrows + 1 elements *)
+        member m.SparseValues =  sparseValues
+
+        member m.ElementOps = 
+              match opsData with 
+              | None -> raise (new System.NotSupportedException("The element type carried by this matrix does not support numeric operations"))
+              | Some a -> a
+
+        member m.MinIndexForRow i = m.SparseRowOffsets.[i]
+        member m.MaxIndexForRow i = m.SparseRowOffsets.[i+1]
+              
+
+        member m.Item 
+            with get (i,j) = 
+                let imax = m.NumRows
+                let jmax = m.NumCols
+                if j < 0 || j >= jmax || i < 0 || i >= imax then raise (new System.ArgumentOutOfRangeException()) else
+                let kmin = m.MinIndexForRow i
+                let kmax = m.MaxIndexForRow i
+                let rec loopRow k =
+                    (* note: could do a binary chop here *)
+                    if k >= kmax then m.ElementOps.Zero else
+                    let j2 = columnValues.[k]
+                    if j < j2 then m.ElementOps.Zero else
+                    if j = j2 then sparseValues.[k] else 
+                    loopRow (k+1)
+                loopRow kmin
+
+#if FX_NO_DEBUG_DISPLAYS
+#else
+    [<System.Diagnostics.DebuggerDisplay("{DebugDisplay}")>]
+#endif
+    [<StructuredFormatDisplay("matrix {StructuredDisplayAsArray}")>]
+    [<CustomEquality; CustomComparison>]
+    //[<System.Diagnostics.DebuggerTypeProxy(typedefof<MatrixDebugView<_>>)>]
+    type Matrix<'T> = 
+        | DenseRepr of DenseMatrix<'T>
+        | SparseRepr of SparseMatrix<'T>
+        interface System.IComparable
+        interface IStructuralComparable
+        interface IStructuralEquatable
+        interface IEnumerable<'T> 
+        interface IEnumerable
+
+        member m.ElementOps = match m with DenseRepr mr -> mr.ElementOps | SparseRepr mr -> mr.ElementOps
+        member m.NumRows    = match m with DenseRepr mr -> mr.NumRows    | SparseRepr mr ->  mr.NumRows
+        member m.NumCols    = match m with DenseRepr mr -> mr.NumCols    | SparseRepr mr ->  mr.NumCols
+
+        member m.Item 
+            with get (i,j) = 
+                match m with 
+                | DenseRepr dm -> dm.[i,j]
+                | SparseRepr sm -> sm.[i,j]
+            and set (i,j) x = 
+              match m with 
+              | DenseRepr dm -> dm.[i,j] <- x
+              | SparseRepr _ -> sparseNotMutable()
+
+
+#if FX_NO_DEBUG_DISPLAYS
+#else
+        [<DebuggerBrowsable(DebuggerBrowsableState.Collapsed)>]
+#endif
+        member m.IsDense = match m with DenseRepr _ -> true | SparseRepr _ -> false
+
+#if FX_NO_DEBUG_DISPLAYS
+#else
+        [<DebuggerBrowsable(DebuggerBrowsableState.Collapsed)>]
+#endif
+        member m.IsSparse = match m with DenseRepr _ -> false | SparseRepr _ -> true
+
+#if FX_NO_DEBUG_DISPLAYS
+#else
+        [<DebuggerBrowsable(DebuggerBrowsableState.Collapsed)>]
+#endif
+        member m.InternalSparseColumnValues = match m with DenseRepr _ -> invalidOp "not a sparse matrix" | SparseRepr mr -> mr.SparseColumnValues
+
+#if FX_NO_DEBUG_DISPLAYS
+#else
+        [<DebuggerBrowsable(DebuggerBrowsableState.Collapsed)>]
+#endif
+        member m.InternalSparseRowOffsets = match m with DenseRepr _ -> invalidOp "not a sparse matrix" | SparseRepr mr -> mr.SparseRowOffsets
+
+#if FX_NO_DEBUG_DISPLAYS
+#else
+        [<DebuggerBrowsable(DebuggerBrowsableState.Collapsed)>]
+#endif
+        member m.InternalSparseValues = match m with DenseRepr _ -> invalidOp "not a sparse matrix" | SparseRepr mr -> mr.SparseValues
+
+#if FX_NO_DEBUG_DISPLAYS
+#else
+        [<DebuggerBrowsable(DebuggerBrowsableState.Collapsed)>]
+#endif
+        member m.InternalDenseValues = match m with DenseRepr mr -> mr.Values | SparseRepr _ -> invalidOp "not a dense matrix"
+
+#if FX_NO_DEBUG_DISPLAYS
+#else
+    [<System.Diagnostics.DebuggerDisplay("{DebugDisplay}")>]
+#endif
+#if FX_NO_DEBUG_PROXIES
+#else
+    [<System.Diagnostics.DebuggerTypeProxy(typedefof<RowVectorDebugView<_>>)>]
+#endif
+    [<StructuredFormatDisplay("rowvec {StructuredDisplayAsArray}")>]
+    [<Sealed>]
+    type RowVector<'T>(opsRV : INumeric<'T> option, arrRV : 'T array ) =
+        interface System.IComparable
+        interface IStructuralComparable
+        interface IStructuralEquatable 
+
+
+#if FX_NO_DEBUG_DISPLAYS
+#else
+        [<DebuggerBrowsable(DebuggerBrowsableState.Collapsed)>]
+#endif
+        member x.InternalValues = arrRV
+        member x.Values = arrRV
+        member x.OpsData = opsRV
+        
+        
+        interface IEnumerable<'T> with 
+            member x.GetEnumerator() = (arrRV :> seq<_>).GetEnumerator()
+        interface IEnumerable  with 
+            member x.GetEnumerator() = (arrRV :> IEnumerable).GetEnumerator()
+
+        member x.Length = arrRV.Length
+        member x.NumCols = arrRV.Length
+        member x.ElementOps = 
+            match opsRV with 
+            | None -> raise (new System.NotSupportedException("The element type carried by this row vector does not support numeric operations"))
+            | Some a -> a
+
+        member v.Item
+           with get i = arrRV.[i]
+           and  set i x = arrRV.[i] <- x
+
+    and 
+        [<Sealed>]
+        RowVectorDebugView<'T>(v: RowVector<'T>)  =  
+
+#if FX_NO_DEBUG_DISPLAYS
+#else
+             [<System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.RootHidden)>]
+#endif
+             member x.Items = v |> Seq.truncate 1000 |> Seq.toArray 
+
+#if FX_NO_DEBUG_DISPLAYS
+#else
+    [<System.Diagnostics.DebuggerDisplay("{DebugDisplay}")>]
+#endif
+#if FX_NO_DEBUG_PROXIES
+#else
+    [<System.Diagnostics.DebuggerTypeProxy(typedefof<VectorDebugView<_>>)>]
+#endif
+    [<StructuredFormatDisplay("vector {StructuredDisplayAsArray}")>]
+    [<Sealed>]
+    type Vector<'T>(opsV : INumeric<'T> option, arrV : 'T array) =
+
+#if FX_NO_DEBUG_DISPLAYS
+#else
+        [<DebuggerBrowsable(DebuggerBrowsableState.Collapsed)>]
+#endif
+        member x.InternalValues = arrV
+        member x.Values = arrV
+        member x.OpsData = opsV
+        interface System.IComparable
+        interface IStructuralComparable
+        interface IStructuralEquatable 
+
+        interface IEnumerable<'T> with 
+            member x.GetEnumerator() = (arrV :> seq<_>).GetEnumerator()
+        interface IEnumerable  with 
+            member x.GetEnumerator() = (arrV :> IEnumerable).GetEnumerator()
+        
+
+        member m.Length = arrV.Length
+        member m.NumRows = arrV.Length
+        member m.ElementOps = 
+            match opsV with 
+            | None -> raise (new System.NotSupportedException("The element type carried by this vector does not support numeric operations"))
+            | Some a -> a
+        member v.Item
+           with get i = arrV.[i]
+           and  set i x = arrV.[i] <- x
+
+#if FX_NO_DEBUG_PROXIES
+#else
+    and 
+        [<Sealed>]
+        VectorDebugView<'T>(v: Vector<'T>)  =  
+
+             [<System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.RootHidden)>]
+             member x.Items = v |> Seq.truncate 1000 |> Seq.toArray 
+#endif
+
+
+    /// Implementations of operations that will work for any type
+    module GenericImpl = 
+
+        type OpsData<'T> = INumeric<'T> option
+
+        let opsOfOpsData (d : OpsData<'T>)  =
+             match d with 
+             | None -> raise (new System.NotSupportedException("The element type '"+(typeof<'T>).ToString()+"' carried by this vector or matrix does not support numeric operations (i.e. does not have a registered numeric association)"))
+             | Some a -> a
+
+        let getNormOps (ops:INumeric<'T>) = 
+            match box ops with
+              | :? INormFloat<'T> as ops -> ops
+              | _ -> raise (new System.NotSupportedException("The element type '"+(typeof<'T>.ToString())+"' carried by this vector or matrix does not support the INormFloat<_> operation (i.e. does not have a registered numeric association that supports this type)"))
+
+        let mkDenseMatrixGU ops arr = DenseMatrix(ops,arr)
+        let mkRowVecGU ops arr = RowVector(ops, arr)
+        let mkVecGU ops arr = Vector(ops,arr)
+
+        let inline getArray2D  (arrDM : _[,]) i j   = arrDM.[i,j]
+        let inline setArray2D  (arrDM  : _[,]) i j x = arrDM.[i,j] <- x
+
+        let inline createArray m = Array.zeroCreate m
+
+        let inline createArray2D m n = Array2D.zeroCreate m n
+
+        let inline assignArray2D m n f arr =  
+            for i = 0 to m - 1 do 
+                for j = 0 to n - 1 do 
+                    (arr  : _[,]).[i,j] <- f i j
+
+        let inline assignConstArray2D m n x arr =  
+            for i = 0 to m - 1 do 
+                for j = 0 to n - 1 do 
+                    (arr  : _[,]).[i,j] <- x
+
+        let inline assignDenseMatrixGU f (a:DenseMatrix<_>) = 
+            assignArray2D a.NumRows a.NumCols f a.Values
+        
+        let inline assignArray m f (arr : _[]) = 
+            for i = 0 to m - 1 do 
+                arr.[i] <- f i
+
+        let inline assignConstArray m x (arr : _[]) = 
+            for i = 0 to m - 1 do 
+                arr.[i] <- x
+
+        let inline assignVecGU f (a:Vector<_>) = 
+            assignArray a.NumRows f a.Values
+        
+        let inline assignRowVecGU f (a:RowVector<_>) = 
+            assignArray a.NumCols f a.Values
+        
+        let createConstDenseMatrixGU ops m n x = 
+            let arr = createArray2D m n 
+            assignConstArray2D m n x arr;
+            DenseMatrix(ops,arr)
+        
+        let createConstRowVecGU ops m x = 
+            let arr = createArray m 
+            assignConstArray m x arr;
+            mkRowVecGU ops arr
+        
+        let createConstVecGU ops m x = 
+            let arr = createArray m 
+            assignConstArray m x arr;
+            mkVecGU ops arr
+
+
+        let inline createDenseMatrixGU ops m n f = (* inline eliminates unknown f call *)
+            let arr = createArray2D m n 
+            assignArray2D m n f arr;
+            DenseMatrix(ops,arr)
+        
+        let createRowVecGU ops m f = 
+            let arr = createArray m 
+            assignArray m f arr;
+            mkRowVecGU ops arr
+        
+        let inline createVecGU ops m f = (* inline eliminates unknown f call *)
+            let arr = createArray m 
+            assignArray m f arr;
+            mkVecGU ops arr
+
+        /// Create a matrix from a sparse sequence 
+        let initSparseMatrixGU maxi maxj ops s = 
+
+            (* nb. could use sorted dictionary but that is in System.dll *)
+            let tab = Array.create maxi null
+            let count = ref 0
+            for (i,j,v) in s do
+                if i < 0 || i >= maxi || j <0 || j >= maxj then failwith "initial value out of range";
+                count := !count + 1;
+                let tab2 = 
+                    match tab.[i] with 
+                    | null -> 
+                        let tab2 = new Dictionary<_,_>(3) 
+                        tab.[i] <- tab2;
+                        tab2
+                    | tab2 -> tab2
+                tab2.[j] <- v
+            // optimize this line....
+            let offsA =  
+               let rowsAcc = Array.zeroCreate (maxi + 1)
+               let mutable acc = 0 
+               for i = 0 to maxi-1 do 
+                  rowsAcc.[i] <- acc;
+                  acc <- match tab.[i] with 
+                          | null -> acc
+                          | tab2 -> acc+tab2.Count
+               rowsAcc.[maxi] <- acc;
+               rowsAcc
+               
+            let colsA,valsA = 
+               let colsAcc = new ResizeArray<_>(!count)
+               let valsAcc = new ResizeArray<_>(!count)
+               for i = 0 to maxi-1 do 
+                  match tab.[i] with 
+                  | null -> ()
+                  | tab2 -> tab2 |> Seq.toArray |> Array.sortBy (fun kvp -> kvp.Key) |> Array.iter (fun kvp -> colsAcc.Add(kvp.Key); valsAcc.Add(kvp.Value));
+               colsAcc.ToArray(), valsAcc.ToArray()
+
+            SparseMatrix(opsData=ops, sparseValues=valsA, sparseRowOffsets=offsA, ncols=maxj, columnValues=colsA)
+        
+        let zeroizeDenseMatrixGUA arr  m n : DenseMatrix<'T> = 
+            let opsData = opsdata<'T> 
+            let ops = opsOfOpsData opsData 
+            let zero = ops.Zero 
+            assignArray2D m n (fun _ _ -> zero) arr;
+            DenseMatrix(opsData,arr)
+
+        let zeroizeArray opsData arr m  = 
+            let ops = opsOfOpsData opsData 
+            let zero = ops.Zero 
+            assignArray m (fun _ -> zero) arr
+
+        let zeroizeVecGUA arr m  : Vector<'T> = 
+            let opsData = opsdata<'T> 
+            zeroizeArray opsData arr m;
+            mkVecGU opsData arr
+
+        let zeroizeRowVecGUA arr m  : RowVector<'T> = 
+            let opsData = opsdata<'T> 
+            zeroizeArray opsData arr m;
+            mkRowVecGU opsData arr
+
+        let listDenseMatrixGU ops xss =
+            let m = List.length xss
+            match xss with 
+            | [] -> invalidArg "xss" "unexpected empty list"
+            | h :: t -> 
+              let n = List.length h
+              if not (List.forall (fun xs -> List.length xs=n) t) then invalidArg "xss" "the lists are not all of the same length";
+              let values = Array2D.zeroCreate m n
+              List.iteri (fun i rw -> List.iteri (fun j x -> values.[i,j] <- x) rw) xss;
+              DenseMatrix(ops,values)
+        
+        let listRowVecGU ops xs = mkRowVecGU ops (Array.ofList xs) 
+        let listVecGU ops xs = mkVecGU ops (Array.ofList xs) 
+
+        let seqDenseMatrixGU ops xss = listDenseMatrixGU ops (xss |> Seq.toList |> List.map Seq.toList)
+        let seqVecGU  ops xss = listVecGU ops (xss |> Seq.toList)
+        let seqRowVecGU ops xss = listRowVecGU ops (xss |> Seq.toList)
+
+        let inline binaryOpDenseMatrixGU f (a:DenseMatrix<_>) (b:DenseMatrix<_>) = (* pointwise binary operator *)
+            let nA = a.NumCols
+            let mA = a.NumRows
+            let nB = b.NumCols 
+            let mB = b.NumRows
+            if nA<>nB || mA<>mB then invalidArg "a" "the two matrices do not have compatible dimensions";
+            let arrA = a.Values 
+            let arrB = b.Values 
+            createDenseMatrixGU a.OpsData mA nA (fun i j -> f (getArray2D arrA i j) (getArray2D arrB i j))
+
+
+        let nonZeroEntriesSparseMatrixGU  (a:SparseMatrix<_>) = 
+            // This is heavily used, and this version is much faster than
+            // the sequence operators.
+            let entries = new ResizeArray<_>(a.SparseColumnValues.Length)
+            let imax = a.NumRows
+            let ops = a.ElementOps 
+            let zero = ops.Zero
+            for i in 0 .. imax - 1 do
+              let kmin = a.MinIndexForRow i
+              let kmax = a.MaxIndexForRow i
+              for k in kmin .. kmax - 1 do
+                  let j = a.SparseColumnValues.[k]
+                  let v = a.SparseValues.[k]
+                  if not (ops.Equals(v,zero)) then
+                    entries.Add((i,j,v))
+            (entries :> seq<_>)
+
+        let nonzeroEntriesDenseMatrixGU  (a:DenseMatrix<_>) = 
+            let imax = a.NumRows
+            let jmax = a.NumCols
+            let ops = a.ElementOps 
+            let zero = ops.Zero
+            seq { for i in 0 .. imax - 1 do 
+                    for j in 0 .. jmax - 1 do 
+                        let v = a.[i,j] 
+                        if not (ops.Equals(v, zero)) then
+                             yield (i,j,v) }
+
+
+        // pointwise operation on two sparse matrices. f must be zero-zero-preserving, i.e. (f 0 0 = 0) 
+        let binaryOpSparseMatrixGU f (a:SparseMatrix<_>) (b:SparseMatrix<_>) = 
+            let ops = a.ElementOps 
+            let zero = ops.Zero
+            let imax1 = a.NumRows  
+            let imax2 = b.NumRows
+            let jmax1 = a.NumCols
+            let jmax2 = b.NumCols
+            if imax1 <> imax2 || jmax1 <> jmax2 then invalidArg "b" "the two matrices do not have compatible dimensions";
+            let imin = 0
+            let imax = imax1
+            let jmax = jmax1
+            let rowsR = Array.zeroCreate (imax+1)
+            let colsR = new ResizeArray<_>(max a.SparseColumnValues.Length b.SparseColumnValues.Length)
+            let valsR = new ResizeArray<_>(max a.SparseValues.Length b.SparseValues.Length)
+            let rec loopRows i  = 
+                rowsR.[i] <- valsR.Count;            
+                if i >= imax1 then () else
+                let kmin1 = a.MinIndexForRow i
+                let kmax1 = a.MaxIndexForRow i 
+                let kmin2 = b.MinIndexForRow i
+                let kmax2 = b.MaxIndexForRow i
+                let rec loopRow k1 k2  =
+                    if k1 >= kmax1 && k2 >= kmax2 then () else
+                    let j1 = if k1 >= kmax1 then jmax else a.SparseColumnValues.[k1]
+                    let j2 = if k2 >= kmax2 then jmax else b.SparseColumnValues.[k2]
+                    let v1 = if j1 <= j2 then a.SparseValues.[k1] else zero
+                    let v2 = if j2 <= j1 then b.SparseValues.[k2] else zero
+                    let jR = min j1 j2
+                    let vR = f v1 v2
+                    (* if vR <> zero then  *)
+                    colsR.Add(jR);
+                    valsR.Add(vR);
+                    loopRow (if j1 <= j2 then k1+1 else k1) (if j2 <= j1 then k2+1 else k2)
+                loopRow kmin1 kmin2;
+                loopRows (i+1) 
+            loopRows imin;
+            SparseMatrix(opsData= a.OpsData, 
+                         sparseRowOffsets=rowsR, 
+                         ncols= a.NumCols, 
+                         columnValues=colsR.ToArray(), 
+                         sparseValues=valsR.ToArray())
+
+        let inline binaryOpRowVecGU f (a:RowVector<_>) (b:RowVector<_>) = (* pointwise binary operator *)
+            let mA = a.NumCols
+            let mB = b.NumCols
+            if mA<>mB then invalidArg "b" "the two vectors do not have compatible dimensions"
+            createRowVecGU a.OpsData mA (fun i -> f a.[i] b.[i])
+
+        let inline binaryOpVecGU f (a:Vector<_>) (b:Vector<_>) = (* pointwise binary operator *)
+            let mA = a.NumRows
+            let mB = b.NumRows
+            if mA<>mB then invalidArg "b" "the two vectors do not have compatible dimensions"
+            createVecGU a.OpsData mA (fun i -> f a.[i] b.[i])
+
+        let inline unaryOpDenseMatrixGU f (a:DenseMatrix<_>) =
+            let nA = a.NumCols 
+            let mA = a.NumRows 
+            let arrA = a.Values 
+            createDenseMatrixGU a.OpsData mA nA (fun i j -> f (getArray2D arrA i j))
+
+        let inline unaryOpRowVecGU f (a:RowVector<_>) =
+            let mA = a.NumCols
+            let arrA = a.Values 
+            createRowVecGU a.OpsData mA (fun j -> f arrA.[j])
+
+        let inline unaryOpVectorGU f (a:Vector<_>) =
+            let mA = a.NumRows 
+            let arrA = a.Values 
+            createVecGU a.OpsData mA (fun i -> f arrA.[i])
+
+        let unaryOpSparseGU f (a:SparseMatrix<_>) = (* pointwise zero-zero-preserving binary operator (f 0 = 0) *)
+            SparseMatrix(opsData=a.OpsData,
+                         sparseRowOffsets=Array.copy a.SparseRowOffsets, 
+                         columnValues=Array.copy a.SparseColumnValues, 
+                         sparseValues=Array.map f a.SparseValues, 
+                         ncols=a.NumCols)
+
+        // Strictly speaking, sparse arrays are non mutable so no copy is ever needed. But implementing it *)
+        // anyway in case we move to mutability *)
+        let copySparseGU (a:SparseMatrix<_>) = 
+            SparseMatrix(opsData=a.OpsData,
+                         sparseRowOffsets=Array.copy a.SparseRowOffsets, 
+                         columnValues=Array.copy a.SparseColumnValues,
+                         sparseValues=Array.copy a.SparseValues, 
+                         ncols=a.NumCols)
+
+        let addDenseMatrixGU  (a:DenseMatrix<_>)  b = let ops = a.ElementOps in binaryOpDenseMatrixGU (fun x y -> ops.Add(x, y)) a b
+        let addSparseMatrixGU (a:SparseMatrix<_>) b = let ops = a.ElementOps in binaryOpSparseMatrixGU (fun x y -> ops.Add(x, y)) a b
+        let addRowVecGU       (a:RowVector<_>)    b = let ops = a.ElementOps in binaryOpRowVecGU (fun x y -> ops.Add(x, y)) a b
+        let addVecGU          (a:Vector<_>)       b = let ops = a.ElementOps in binaryOpVecGU  (fun x y -> ops.Add(x, y)) a b 
+
+        let subDenseMatrixGU  (a:DenseMatrix<_>)  b = let ops = a.ElementOps in binaryOpDenseMatrixGU (fun x y -> ops.Subtract(x, y)) a b
+        let subSparseMatrixGU (a:SparseMatrix<_>) b = let ops = a.ElementOps in binaryOpSparseMatrixGU (fun x y -> ops.Subtract(x, y)) a b
+        let subRowVecGU       (a:RowVector<_>)    b = let ops = a.ElementOps in binaryOpRowVecGU (fun x y -> ops.Subtract(x, y)) a b
+        let subVecGU          (a:Vector<_>)       b = let ops = a.ElementOps in binaryOpVecGU  (fun x y -> ops.Subtract(x, y)) a b 
+
+        ///Point-wise multiplication 
+        let cptMulDenseMatrixGU  (a:DenseMatrix<_>)  b = let ops = a.ElementOps in binaryOpDenseMatrixGU  (fun x y -> ops.Multiply(x, y)) a b
+        let cptMulSparseMatrixGU (a:SparseMatrix<_>) b = let ops = a.ElementOps in binaryOpSparseMatrixGU  (fun x y -> ops.Multiply(x, y)) a b
+        let cptMulRowVecGU       (a:RowVector<_>)    b = let ops = a.ElementOps in binaryOpRowVecGU (fun x y -> ops.Multiply(x, y)) a b
+        let cptMulVecGU          (a:Vector<_>)       b = let ops = a.ElementOps in binaryOpVecGU  (fun x y -> ops.Multiply(x, y)) a b
+
+        let cptMaxDenseMatrixGU  (a:DenseMatrix<_>) b = binaryOpDenseMatrixGU  max a b
+        let cptMinDenseMatrixGU  (a:DenseMatrix<_>) b = binaryOpDenseMatrixGU  min a b
+        let cptMaxSparseMatrixGU (a:SparseMatrix<_>) b = binaryOpSparseMatrixGU  max a b
+        let cptMinSparseMatrixGU (a:SparseMatrix<_>) b = binaryOpSparseMatrixGU  min a b
+
+        let cptMaxVecGU (a:Vector<_>) b = binaryOpVecGU max a b
+        let cptMinVecGU (a:Vector<_>) b = binaryOpVecGU min a b
+
+        let add (ops : INumeric<'T>) x y = ops.Add(x,y) 
+        let sub (ops : INumeric<'T>) x y = ops.Subtract(x,y) 
+        let mul (ops : INumeric<'T>) x y = ops.Multiply(x,y) 
+
+        let inline foldR f z (a,b) = 
+            let mutable res = z in
+            for i = a to b do
+                res <- f res i
+            res
+
+        let inline sumfR f (a,b) =
+            let mutable res = 0.0 
+            for i = a to b do
+                res <- res + f i
+            res
+          
+
+        let inline sumRGU (ops : INumeric<_>) f r = 
+            let zero = ops.Zero 
+            r |> foldR (fun z k -> add ops z (f k)) zero
+
+        let genericMulDenseMatrix (a:DenseMatrix<_>) (b:DenseMatrix<_>) =
+            let nA = a.NumCols 
+            let mA = a.NumRows
+            let nB = b.NumCols 
+            let mB = b.NumRows
+            if nA<>mB then invalidArg "b" "the two matrices do not have compatible dimensions"
+            let ops = a.ElementOps 
+            let arrA = a.Values 
+            let arrB = b.Values 
+            createDenseMatrixGU a.OpsData mA nB
+              (fun i j -> (0,nA - 1) |> sumRGU ops (fun k -> mul ops (getArray2D arrA i k) (getArray2D arrB k j)))
+
+        let debug = false
+        
+        // SParse matrix multiplication algorithm. inline to get specialization at the 'double' type
+        let inline genericMulSparse zero add mul (a:SparseMatrix<_>) (b:SparseMatrix<_>) =
+            let nA = a.NumCols
+            let mA = a.NumRows
+            let nB = b.NumCols 
+            let mB = b.NumRows
+            if nA<>mB then invalidArg "b" "the two matrices do not have compatible dimensions"
+            let C = new ResizeArray<_>()
+            let jC = new ResizeArray<_>()
+            let MA1 = mA + 1 
+            let offsAcc = Array.zeroCreate MA1
+            let index = Array.zeroCreate mA
+            let temp = Array.create mA zero
+            let ptr = new Dictionary<_,_>(11)
+            if debug then printf "start, #items in result = %d, #offsAcc = %d, mA = %d\n" jC.Count offsAcc.Length mA;
+
+            let mutable mlast = 0
+            for i = 0 to mA-1 do
+                if debug then printf "i = %d, mlast = %d\n" i mlast;
+                offsAcc.[i] <- mlast
+                
+                let kmin1 = a.MinIndexForRow i
+                let kmax1 = a.MaxIndexForRow i
+                if kmin1 < kmax1 then 
+                    let mutable itemp = 0
+                    let mutable ptrNeedsClear = true // clear the ptr table on demand. 
+                    for j = kmin1 to kmax1 - 1 do
+                        if debug then printf "  j = %d\n" j;
+                        let ja_j = a.SparseColumnValues.[j]
+                        let kmin2 = b.MinIndexForRow ja_j
+                        let kmax2 = b.MaxIndexForRow ja_j
+                        for k = kmin2 to kmax2 - 1 do
+                            let jb_k = b.SparseColumnValues.[k]
+                            if debug then printf "    i = %d, j = %d, k = %d, ja_j = %d, jb_k = %d\n" i j k ja_j jb_k;
+                            let va = a.SparseValues.[j] 
+                            let vb = b.SparseValues.[k]
+                            if debug then printf "    va = %O, vb = %O\n" va vb;
+                            let summand = mul va vb
+                            if debug then printf "    summand = %O\n" summand;
+                            if ptrNeedsClear then (ptr.Clear();ptrNeedsClear <- false);
+
+                            if not (ptr.ContainsKey(jb_k)) then
+                                if debug then printf "    starting entry %d\n" jb_k;
+                                ptr.[jb_k] <- itemp
+                                let ptr_jb_k = itemp
+                                temp.[ptr_jb_k] <- summand
+                                index.[ptr_jb_k] <- jb_k
+                                itemp <- itemp + 1
+                            else
+                                if debug then printf "    adding to entry %d\n" jb_k;
+                                let ptr_jb_k = ptr.[jb_k]
+                                temp.[ptr_jb_k] <- add temp.[ptr_jb_k] summand
+                        done
+                    done
+                    if itemp > 0 then 
+                        // Sort by index. 
+                        // REVIEW: avoid the allocations here
+                        let sorted = (temp.[0..itemp-1],index.[0..itemp-1]) ||> Array.zip 
+                        Array.sortInPlaceBy (fun (_,idx) -> idx) sorted
+                        for s = 0 to itemp-1 do
+                            let (v,idx) = sorted.[s]
+                            if debug then printf "  writing value %O at index %d to result matrix\n" v idx;
+                            C.Add(v)
+                            jC.Add(idx)
+                        if debug then printf " itemp = %d, mlast = %d\n" itemp mlast;
+                        mlast <- mlast + itemp 
+            done
+            offsAcc.[mA] <- mlast;
+            if debug then printf "done, #items in result = %d, #offsAcc = %d, mA = %d\n" jC.Count offsAcc.Length mA;
+            SparseMatrix(opsData = a.OpsData,
+                         sparseRowOffsets=offsAcc,
+                         ncols= nB,
+                         columnValues=jC.ToArray(),
+                         sparseValues=C.ToArray())
+
+        let mulSparseMatrixGU (a: SparseMatrix<_>) b =
+            let ops = a.ElementOps 
+            let zero = ops.Zero
+            genericMulSparse zero (add ops) (mul ops) a b
+
+
+        let mulRowVecVecGU (a:RowVector<_>) (b:Vector<_>) =
+            let mA = a.NumCols 
+            let nB = b.NumRows 
+            if mA<>nB then invalidArg "b" "the two vectors do not have compatible dimensions"
+            let ops = a.ElementOps 
+            (0,mA - 1) |> sumRGU ops (fun k -> mul ops a.[k] b.[k])
+
+        let rowvecDenseMatrixGU (x:RowVector<_>) = createDenseMatrixGU x.OpsData 1         x.NumCols (fun _ j -> x.[j]) 
+        let vectorDenseMatrixGU (x:Vector<_>)    = createDenseMatrixGU x.OpsData  x.NumRows 1         (fun i _ -> x.[i]) 
+
+        let mulVecRowVecGU a b = genericMulDenseMatrix (vectorDenseMatrixGU a) (rowvecDenseMatrixGU b)
+
+        let mulRowVecDenseMatrixGU (a:RowVector<_>) (b:DenseMatrix<_>) =
+            let    nA = a.NumCols 
+            let nB = b.NumCols
+            let mB = b.NumRows 
+            if nA<>mB then invalidArg "b" "the two vectors do not have compatible dimensions"
+            let ops = a.ElementOps 
+            let arrA = a.Values 
+            let arrB = b.Values 
+            createRowVecGU a.OpsData nB 
+              (fun j -> (0,nA - 1) |> sumRGU ops (fun k -> mul ops arrA.[k] (getArray2D arrB k j)))
+
+        let mulDenseMatrixVecGU (a:DenseMatrix<_>) (b:Vector<_>) =
+            let nA = a.NumCols 
+            let mA = a.NumRows 
+            let mB    = b.NumRows
+            if nA<>mB then invalidArg "b" "the two inputs do not have compatible dimensions"
+            let ops = b.ElementOps 
+            let arrA = a.Values 
+            let arrB = b.Values 
+            createVecGU b.OpsData mA
+              (fun i -> (0,nA - 1) |> sumRGU ops (fun k -> mul ops (getArray2D arrA i k) arrB.[k]))
+
+        let mulSparseVecGU (a:SparseMatrix<_>) (b:Vector<_>) =
+            let nA = a.NumCols 
+            let mA = a.NumRows 
+            let mB    = b.NumRows 
+            if nA<>mB then invalidArg "b" "the two inputs do not have compatible dimensions"
+            let ops = b.ElementOps 
+            let zero = ops.Zero
+            createVecGU b.OpsData mA (fun i -> 
+                let mutable acc = zero
+                for k = a.MinIndexForRow i to a.MaxIndexForRow i - 1 do
+                    let j = a.SparseColumnValues.[k]
+                    let v = a.SparseValues.[k] 
+                    acc <- add ops acc (mul ops v b.[j]);
+                acc)
+
+        let mulRVSparseMatrixGU (a:RowVector<_>) (b:SparseMatrix<_>) =
+            let nA = b.NumCols
+            let mA = b.NumRows 
+            let mB    = a.NumCols 
+            if mA<>mB then invalidArg "b" "the two inputs do not have compatible dimensions"
+            let ops = b.ElementOps 
+            let arr = createArray nA 
+            zeroizeArray a.OpsData arr nA;
+            for i = 0 to mA - 1 do
+                for k = b.MinIndexForRow i to b.MaxIndexForRow i - 1 do
+                    let j = b.SparseColumnValues.[k]
+                    let v = b.SparseValues.[k] 
+                    arr.[j] <- add ops arr.[j] (mul ops a.[i] v)
+            mkRowVecGU a.OpsData arr
+
+
+        let scaleDenseMatrixGU  k (a:DenseMatrix<_>)  = let ops = a.ElementOps in unaryOpDenseMatrixGU (fun x -> ops.Multiply(k,x)) a
+        let scaleRowVecGU       k (a:RowVector<_>)    = let ops = a.ElementOps in unaryOpRowVecGU (fun x -> ops.Multiply(k,x)) a
+        let scaleVecGU          k (a:Vector<_>)       = let ops = a.ElementOps in unaryOpVectorGU  (fun x -> ops.Multiply(k,x)) a
+        let scaleSparseMatrixGU k (a:SparseMatrix<_>) = let ops = a.ElementOps in unaryOpSparseGU (fun x -> ops.Multiply(k,x)) a
+        let negDenseMatrixGU  (a:DenseMatrix<_>)  = let ops = a.ElementOps in unaryOpDenseMatrixGU (fun x -> ops.Negate(x)) a
+        let negRowVecGU       (a:RowVector<_>)    = let ops = a.ElementOps in unaryOpRowVecGU (fun x -> ops.Negate(x)) a
+        let negVecGU          (a:Vector<_>)       = let ops = a.ElementOps in unaryOpVectorGU  (fun x -> ops.Negate(x)) a
+        let negSparseMatrixGU (a:SparseMatrix<_>) = let ops = a.ElementOps in unaryOpSparseGU (fun x -> ops.Negate(x)) a
+
+        let mapDenseMatrixGU f (a : DenseMatrix<'T>) : DenseMatrix<'T> = 
+            let arrA = a.Values 
+            createDenseMatrixGU a.OpsData a.NumRows a.NumCols (fun i j -> f (getArray2D arrA i j))
+
+        let mapVecGU f (a:Vector<_>) = 
+            let mA= a.NumRows
+            createVecGU a.OpsData mA (fun i -> f a.[i])
+
+        let copyDenseMatrixGU (a : DenseMatrix<'T>) : DenseMatrix<'T> = 
+            let arrA = a.Values 
+            createDenseMatrixGU a.OpsData a.NumRows a.NumCols (fun i j -> getArray2D arrA i j)
+
+        let copyVecGU (a:Vector<_>) = 
+            createVecGU a.OpsData a.NumRows (fun i -> a.[i])
+
+        let copyRowVecGU (a:RowVector<_>) = 
+            createRowVecGU a.OpsData a.NumCols (fun i -> a.[i])
+
+        let toDenseSparseMatrixGU (a:SparseMatrix<_>) = 
+            createDenseMatrixGU a.OpsData a.NumRows a.NumCols  (fun i j -> a.[i,j])
+          
+        let mapiDenseMatrixGU f (a: DenseMatrix<'T>) : DenseMatrix<'T> = 
+            let arrA = a.Values 
+            createDenseMatrixGU a.OpsData a.NumRows a.NumCols (fun i j -> f i j (getArray2D arrA i j))
+
+        let mapiRowVecGU f (a:RowVector<_>) = 
+            createRowVecGU a.OpsData a.NumCols (fun i -> f i a.[i])
+
+        let mapiVecGU f (a:Vector<_>) = 
+            createVecGU a.OpsData a.NumRows (fun i -> f i a.[i])
+
+        let permuteVecGU (p:permutation) (a:Vector<_>) = 
+            createVecGU a.OpsData a.NumRows (fun i -> a.[p i])
+
+        let permuteRowVecGU (p:permutation) (a:RowVector<_>) = 
+            createRowVecGU a.OpsData a.NumCols (fun i -> a.[p i])
+
+        let inline inplace_mapiDenseMatrixGU f (a:DenseMatrix<_>) = 
+            let arrA = a.Values 
+            assignDenseMatrixGU (fun i j -> f i j (getArray2D arrA i j)) a
+
+        let inline inplace_mapiRowVecGU f (a:RowVector<_>) = 
+            assignRowVecGU (fun i -> f i a.[i]) a
+
+        let inline inplace_mapiVecGU f (a:Vector<_>) = 
+            assignVecGU (fun i -> f i a.[i]) a
+
+        let inline foldDenseMatrixGU f z (a:DenseMatrix<_>) =
+            let nA = a.NumCols 
+            let mA = a.NumRows
+            let arrA = a.Values 
+            let mutable acc = z
+            for i = 0 to mA-1 do
+                for j = 0 to nA-1 do 
+                   acc <- f acc (getArray2D arrA i j)
+            acc
+        
+        let inline foldVecGU f z (a:Vector<_>) =
+            let mutable acc = z
+            for i = 0 to a.NumRows-1 do acc <- f acc a.[i]
+            acc
+        
+        let inline foldiDenseMatrixGU f z (a:DenseMatrix<_>) =
+            let nA = a.NumCols 
+            let mA = a.NumRows
+            let arrA = a.Values 
+            let mutable acc = z
+            for i = 0 to mA-1 do
+                for j = 0 to nA-1 do 
+                   acc <- f i j acc (getArray2D arrA i j)
+            acc
+        
+        let inline foldiVecGU f z (a:Vector<_>) =
+            let mA = a.NumRows
+            let mutable acc = z
+            for i = 0 to mA-1 do acc <- f i acc a.[i]
+            acc
+        
+        let rec forallR f (n,m) = (n > m) || (f n && forallR f (n+1,m))
+        let rec existsR f (n,m) = (n <= m) && (f n || existsR f (n+1,m))
+        
+        let foralliDenseMatrixGU pred (a:DenseMatrix<_>) =
+            let nA = a.NumCols 
+            let mA = a.NumRows
+            let arrA = a.Values 
+            (0,mA-1) |> forallR  (fun i ->
+            (0,nA-1) |> forallR  (fun j ->
+            pred i j (getArray2D arrA i j)))
+
+        let foralliVecGU pred (a:Vector<_>) =
+            let mA = a.NumRows
+            (0,mA-1) |> forallR  (fun i ->
+            pred i a.[i])
+
+        let existsiDenseMatrixGU pred (a:DenseMatrix<_>) =
+            let nA = a.NumCols 
+            let mA = a.NumRows
+            let arrA = a.Values 
+            (0,mA-1) |> existsR (fun i ->
+            (0,nA-1) |> existsR (fun j ->
+            pred i j (getArray2D arrA i j)))
+
+        let existsiVecGU pred (a:Vector<_>) =
+            let mA = a.NumRows
+            (0,mA-1) |> existsR (fun i ->
+            pred i a.[i])
+
+        let sumDenseMatrixGU  (a:DenseMatrix<_>) = 
+            let ops = a.ElementOps 
+            foldDenseMatrixGU (fun acc aij -> add ops acc aij) ops.Zero a
+
+        let sumSparseMatrixGU  (a:SparseMatrix<_>) = 
+            let ops = a.ElementOps 
+            a |> nonZeroEntriesSparseMatrixGU |> Seq.fold (fun acc (_,_,aij) -> add ops acc aij) ops.Zero
+
+        let sumVecGU (a:Vector<_>) = 
+            let ops = a.ElementOps 
+            foldVecGU (fun acc ai -> add ops acc ai) ops.Zero a
+
+        let prodDenseMatrixGU (a:DenseMatrix<_>) = 
+            let ops = a.ElementOps 
+            foldDenseMatrixGU (fun acc aij -> mul ops acc aij) ops.One a
+
+        let prodSparseMatrixGU  (a:SparseMatrix<_>) = a |> toDenseSparseMatrixGU |> prodDenseMatrixGU
+
+        let inline fold2DenseMatrixGU f z (a:DenseMatrix<_>) (b:DenseMatrix<_>) =
+            let nA = a.NumCols 
+            let mA = a.NumRows
+            let nB = b.NumCols 
+            let mB = b.NumRows
+            if nA <> nB || mA <> mB then invalidArg "b" "the two matrices do not have compatible dimensions"
+            let arrA = a.Values 
+            let arrB = b.Values 
+            let mutable acc = z
+            for i = 0 to mA-1 do
+                for j = 0 to nA-1 do 
+                   acc <- f acc (getArray2D arrA i j) (getArray2D arrB i j)
+            acc
+
+        let inline fold2VecGU f z (a:Vector<_>) (b:Vector<_>) =
+            let mA = a.NumRows
+            let mB = b.NumRows
+            if  mA <> mB then invalidArg "b" "the two vectors do not have compatible dimensions"
+            let mutable acc = z
+            for i = 0 to mA-1 do acc <- f acc a.[i] b.[i]
+            acc
+
+        let dotDenseMatrixGU (a:DenseMatrix<_>) b =
+            let ops = a.ElementOps 
+            fold2DenseMatrixGU (fun z va vb -> add ops z (mul ops va vb)) ops.Zero a b
+
+        let dotVecGU (a:Vector<_>) b =
+            let ops =   a.ElementOps
+            let zero = ops.Zero 
+            fold2VecGU  (fun z va vb -> add ops z (mul ops va vb)) zero a b 
+
+        let normDenseMatrixGU (a:DenseMatrix<_>) = 
+            let normOps = getNormOps a.ElementOps
+            foldDenseMatrixGU (fun z aij -> z + ((normOps.Norm aij)**2.0)) 0.0 a |> sqrt
+
+        let normSparseMatrixGU (a:SparseMatrix<_>) = 
+            let normOps = getNormOps a.ElementOps
+            a |> nonZeroEntriesSparseMatrixGU |> Seq.fold (fun acc (_,_,aij) -> acc + ((normOps.Norm aij)**2.0)) 0.0 |> sqrt
+
+        let inplaceAddDenseMatrixGU  (a:DenseMatrix<_>) (b:DenseMatrix<_>) = 
+            let ops = a.ElementOps 
+            let arrB = b.Values 
+            inplace_mapiDenseMatrixGU  (fun i j x -> add ops x (getArray2D arrB i j)) a
+        
+        let inplaceAddVecGU  (a:Vector<_>) (b:Vector<_>) = 
+            let ops = a.ElementOps 
+            inplace_mapiVecGU  (fun i x   -> add ops x b.[i]) a
+
+        let inplaceAddRowVecGU (a:RowVector<_>) (b:Vector<_>) = 
+            let ops = a.ElementOps 
+            inplace_mapiRowVecGU (fun i x   -> add ops x b.[i]) a
+
+        let inplaceSubDenseMatrixGU  (a:DenseMatrix<_>) (b:DenseMatrix<_>) = 
+            let ops = a.ElementOps 
+            let arrB = b.Values 
+            inplace_mapiDenseMatrixGU  (fun i j x -> sub ops x (getArray2D  arrB i j)) a
+
+        let inplaceSubVecGU (a:Vector<_>) (b:Vector<_>) = 
+            let ops = a.ElementOps
+            inplace_mapiVecGU  (fun i x   -> sub ops x b.[i]) a
+
+        let inplaceSubRowVecGU (a:RowVector<_>) (b:Vector<_>) = 
+            let ops = a.ElementOps 
+            inplace_mapiRowVecGU (fun i x   -> sub ops x b.[i]  ) a
+
+        let inplaceCptMulDenseMatrixGU  (a:DenseMatrix<_>) (b:DenseMatrix<_>) = 
+            let ops = a.ElementOps 
+            let arrB = b.Values 
+            inplace_mapiDenseMatrixGU  (fun i j x -> mul ops x (getArray2D  arrB i j)) a
+
+        let inplaceCptMulVecGU (a:Vector<_>) (b:Vector<_>) = 
+            let ops = a.ElementOps  
+            inplace_mapiVecGU  (fun i x   -> mul ops x b.[i]) a
+
+        let inplaceCptMulRowVecGU (a:RowVector<_>) (b:Vector<_>) = 
+            let ops = a.ElementOps 
+            inplace_mapiRowVecGU (fun i x   -> mul ops x b.[i]  ) a
+
+        let inplaceScaleDenseMatrixGU  x (a:DenseMatrix<_>) = 
+            let ops = a.ElementOps 
+            inplace_mapiDenseMatrixGU  (fun _ _ y -> ops.Multiply(x,y)) a
+
+        let inplaceScaleVecGU  x (a:Vector<_>) = 
+            let ops = a.ElementOps  
+            inplace_mapiVecGU  (fun _ y   -> ops.Multiply(x,y)) a
+
+        let inplaceScaleRowVecGU x (a:RowVector<_>) = 
+            let ops = a.ElementOps 
+            inplace_mapiRowVecGU (fun _ y   -> ops.Multiply(x,y)) a
+
+
+        let wrapList (pre,mid,post,trim) show l = 
+            let post = if trim then "; ..." + post else post
+            match l with 
+            | []    -> [pre;post]
+            | [x]   -> [pre;show x;post]
+            | x::xs -> [pre;show x] @ (List.collect (fun x -> [mid;show x]) xs) @ [post]
+
+        let showItem opsData  x = 
+            try 
+              let ops = opsOfOpsData opsData 
+              ops.ToString(x,"g10",System.Globalization.CultureInfo.InvariantCulture) 
+            with :? System.NotSupportedException -> (box x).ToString()
+        
+        let mapR f (n,m) = if m < n then [] else List.init (m-n+1) (fun i -> f (n+i))
+
+        let primShowDenseMatrixGU (sepX,sepR) (a : DenseMatrix<'e>) =
+            let nA = min a.NumCols DenseMaxDisplay
+            let mA = min a.NumRows DenseMaxDisplay
+            let ops = a.OpsData 
+            let showLine i = wrapList ("[",";","]", a.NumCols > nA) (showItem ops) ((0,nA-1) |> mapR  (fun j -> a.[i,j])) |> Array.ofList |> System.String.Concat
+            wrapList (string nA + " " + string mA + "matrix [",";"+sepX,"]"+sepR, a.NumRows > mA) showLine [0..mA-1] |> Array.ofList |> System.String.Concat
+
+        let showDenseMatrixGU     m = primShowDenseMatrixGU ("\n","\n") m
+        let debugShowDenseMatrixGU m = primShowDenseMatrixGU (""  ,""  ) m
+        
+        let showVecGU s (a : Vector<_>) =
+            let mA = min a.NumRows VectorMaxDisplay
+            let ops = a.OpsData 
+            wrapList (s+" [",";","]",a.NumRows > mA) (showItem ops) ((0,mA-1) |> mapR  (fun i -> a.[i])) |> Array.ofList |> System.String.Concat 
+
+        let showRowVecGU s (a : RowVector<_>) =
+            let mA = min a.NumCols VectorMaxDisplay
+            let ops = a.OpsData 
+            wrapList (s+" [",";","]",a.NumCols > mA) (showItem ops) ((0,mA-1) |> mapR  (fun i -> a.[i])) |> Array.ofList |> System.String.Concat 
+
+
+    /// Implementations of operations specific to floating point types
+    module DoubleImpl = 
+
+        module GU = GenericImpl
+        open Instances
+        
+        // Element type OpsData
+        //type elem = float
+        let zero = 0.0
+        let one  = 1.0
+        let inline sub (x:float) (y:float) = x - y
+        let inline add (x:float) (y:float) = x + y
+        let inline mul (x:float) (y:float) = x * y
+        let inline neg (x:float) = -x
+
+        // Specialized: these know the relevant set of 
+        // ops without doing a table lookup based on runtime type
+        let FloatOps = Some (FloatNumerics :> INumeric<float>)
+        let inline initDenseMatrixDS m n f = GU.createDenseMatrixGU FloatOps m n f
+        let inline createRowVecDS m f      = GU.createRowVecGU      FloatOps m f
+        let inline createVecDS m f         = GU.createVecGU         FloatOps m f
+        let inline mkDenseMatrixDS  arr    = GU.mkDenseMatrixGU     FloatOps arr
+        let inline mkRowVecDS arr          = GU.mkRowVecGU          FloatOps arr
+        let inline mkVecDS  arr            = GU.mkVecGU             FloatOps arr
+        let inline listDenseMatrixDS  ll   = GU.listDenseMatrixGU   FloatOps ll
+        let inline listRowVecDS l          = GU.listRowVecGU        FloatOps l
+        let inline listVecDS  l            = GU.listVecGU           FloatOps l
+        let inline seqDenseMatrixDS  ll    = GU.seqDenseMatrixGU    FloatOps ll
+        let inline seqRowVecDS l           = GU.seqRowVecGU         FloatOps l
+        let inline seqVecDS  l             = GU.seqVecGU            FloatOps l
+
+        let constDenseMatrixDS  m n x      = GU.createDenseMatrixGU  FloatOps m n (fun _ _ -> x)
+        let constRowVecDS m x              = GU.createRowVecGU FloatOps m   (fun _ -> x)
+        let constVecDS  m x                = GU.createVecGU  FloatOps m   (fun _ -> x)
+        let scalarDenseMatrixDS   x        = constDenseMatrixDS  1 1 x 
+        let scalarRowVecDS  x              = constRowVecDS 1   x 
+        let scalarVecDS   x                = constVecDS  1   x 
+
+        // Beware - when compiled with non-generic code createArray2D creates an array of null values,
+        // not zero values. Hence the optimized version can only be used when compiling with generics.
+        let inline zeroDenseMatrixDS m n = 
+          let arr = GU.createArray2D m n 
+          GU.mkDenseMatrixGU FloatOps arr
+        // Specialized: these inline down to the efficient loops we need
+        let addDenseMatrixDS     a b = GU.binaryOpDenseMatrixGU  add a b
+        let addSparseDS     a b = GU.binaryOpSparseMatrixGU  add a b
+        let addRowVecDS    a b = GU.binaryOpRowVecGU add a b
+        let addVecDS     a b = GU.binaryOpVecGU  add a b
+        let subDenseMatrixDS     a b = GU.binaryOpDenseMatrixGU  sub a b 
+        let subSparseDS     a b = GU.binaryOpSparseMatrixGU  sub a b 
+        let mulSparseDS     a b = GU.genericMulSparse zero add mul a b
+        let subRowVecDS    a b = GU.binaryOpRowVecGU sub a b 
+        let subVecDS     a b = GU.binaryOpVecGU  sub a b 
+        let cptMulDenseMatrixDS  a b = GU.binaryOpDenseMatrixGU  mul a b
+        let cptMulSparseDS  a b = GU.binaryOpSparseMatrixGU  mul a b
+        let cptMulRowVecDS a b = GU.binaryOpRowVecGU mul a b
+        let cptMulVecDS  a b = GU.binaryOpVecGU  mul a b
+        type smatrix = SparseMatrix<float>
+        type dmatrix = DenseMatrix<float>
+        type vector = Vector<float>
+        type rowvec = RowVector<float>
+        let cptMaxDenseMatrixDS  (a:dmatrix) (b:dmatrix) = GU.binaryOpDenseMatrixGU  max a b
+        let cptMinDenseMatrixDS  (a:dmatrix) (b:dmatrix) = GU.binaryOpDenseMatrixGU  min a b
+        let cptMaxSparseDS  (a:smatrix) (b:smatrix) = GU.binaryOpSparseMatrixGU  max a b
+        let cptMinSparseDS  (a:smatrix) (b:smatrix) = GU.binaryOpSparseMatrixGU  min a b
+        let cptMaxVecDS  (a:vector) (b:vector) = GU.binaryOpVecGU  max a b
+        let cptMinVecDS  (a:vector) (b:vector) = GU.binaryOpVecGU  min a b
+
+        // Don't make any mistake about these ones re. performance.
+        let mulDenseMatrixDS (a:dmatrix) (b:dmatrix) =
+            let nA = a.NumCols 
+            let mA = a.NumRows
+            let nB = b.NumCols 
+            let mB = b.NumRows
+            if nA<>mB then invalidArg "b" "the two matrices do not have compatible dimensions"
+            let arr = GU.createArray2D mA nB 
+            let arrA = a.Values 
+            let arrB = b.Values 
+            for i = 0 to mA - 1 do 
+                for j = 0 to nB - 1 do 
+                    let mutable r = 0.0 
+                    for k = 0 to mB - 1 do 
+                        r <- r + mul (GU.getArray2D arrA i k) (GU.getArray2D arrB k j)
+                    GU.setArray2D arr i j r
+            mkDenseMatrixDS arr
+
+        let mulRowVecDenseMatrixDS (a:rowvec) (b:dmatrix) =
+            let nA = a.NumCols 
+            let nB = b.NumCols 
+            let mB = b.NumRows
+            if nA<>mB then invalidArg "b" "the two inputs do not have compatible dimensions"
+            let arr = Array.zeroCreate nB 
+            let arrA = a.Values 
+            let arrB = b.Values 
+            for j = 0 to nB - 1 do 
+                let mutable r = 0.0 
+                for k = 0 to mB - 1 do 
+                    r <- r + mul arrA.[k] (GU.getArray2D arrB k j)
+                arr.[j] <- r
+            mkRowVecDS arr
+
+        let mulDenseMatrixVecDS (a:dmatrix) (b:vector) =
+            let nA = a.NumCols 
+            let mA = a.NumRows
+            let mB = b.NumRows 
+            if nA<>mB then invalidArg "b" "the two inputs do not have compatible dimensions"
+            let arr = Array.zeroCreate mA 
+            let arrA = a.Values 
+            let arrB = b.Values 
+            for i = 0 to mA - 1 do 
+                let mutable r = 0.0 
+                for k = 0 to nA - 1 do 
+                    r <- r + mul (GU.getArray2D arrA i k) arrB.[k]
+                arr.[i] <- r
+            mkVecDS arr
+
+        let mulRowVecVecDS (a:rowvec) (b:vector) =
+            let nA = a.NumCols 
+            let mB = b.NumRows 
+            if nA<>mB then invalidArg "b" "the two vectors do not have compatible dimensions"
+            let arrA = a.Values 
+            let arrB = b.Values 
+            let mutable r = 0.0 
+            for k = 0 to nA - 1 do 
+                r <- r + mul arrA.[k] arrB.[k]
+            r
+
+        let rowvecDenseMatrixDS (x:rowvec) = initDenseMatrixDS 1          x.NumCols (fun _ j -> x.[j]) 
+        let vectorDenseMatrixDS (x:vector) = initDenseMatrixDS x.NumRows  1         (fun i _ -> x.[i]) 
+        let mulVecRowVecDS a b = mulDenseMatrixDS (vectorDenseMatrixDS a) (rowvecDenseMatrixDS b) 
+
+        let scaleDenseMatrixDS   k m = GU.unaryOpDenseMatrixGU  (fun x -> mul k x) m
+        let scaleSparseDS   k m = GU.unaryOpSparseGU  (fun x -> mul k x) m
+        let scaleRowVecDS  k m = GU.unaryOpRowVecGU (fun x -> mul k x) m
+        let scaleVecDS   k m = GU.unaryOpVectorGU  (fun x -> mul k x) m
+        let negDenseMatrixDS     m   = GU.unaryOpDenseMatrixGU  (fun x -> neg x) m
+        let negSparseDS     m   = GU.unaryOpSparseGU  (fun x -> neg x) m
+        let negRowVecDS    m   = GU.unaryOpRowVecGU (fun x -> neg x) m
+        let negVecDS     m   = GU.unaryOpVectorGU  (fun x -> neg x) m
+
+        let traceDenseMatrixDS (a:dmatrix) =
+            let nA = a.NumCols 
+            let mA = a.NumRows
+            if nA<>mA then invalidArg "a" "expected a square matrix";
+            let arrA = a.Values 
+            (0,nA-1) |> GU.sumfR (fun i -> GU.getArray2D arrA i i) 
+
+        let sumDenseMatrixDS  a = GU.foldDenseMatrixGU add zero a
+        let sumVecDS   a = GU.foldVecGU  add zero a
+        let prodDenseMatrixDS a = GU.foldDenseMatrixGU mul one  a
+        let prodVecDS  a = GU.foldVecGU  mul one  a
+
+        let dotDenseMatrixDS a b = GU.fold2DenseMatrixGU (fun z va vb -> add z (mul va vb)) zero a b
+        let dotVecDS a b = GU.fold2VecGU (fun z va vb -> add z (mul va vb)) zero a b
+        let sumfDenseMatrixDS  f m = GU.foldDenseMatrixGU (fun acc aij -> add acc (f aij)) zero m
+        let normDenseMatrixDS m = sqrt (sumfDenseMatrixDS (fun x -> x*x) m)
+
+        let inplaceAddDenseMatrixDS  a (b:DenseMatrix<_>) = let arrB = b.Values  in GU.inplace_mapiDenseMatrixGU  (fun i j x -> x + GU.getArray2D arrB i j) a
+        let inplaceAddVecDS    a (b:Vector<_>) = let arrB = b.Values  in GU.inplace_mapiVecGU  (fun i x   -> x + arrB.[i]) a
+        let inplace_addRowVecDS a (b:RowVector<_>) = let arrB = b.Values in GU.inplace_mapiRowVecGU (fun i x   -> x + arrB.[i]) a
+        let inplaceSubDenseMatrixDS  a (b:DenseMatrix<_>) = let arrB = b.Values  in GU.inplace_mapiDenseMatrixGU  (fun i j x -> x - GU.getArray2D  arrB i j) a
+        let inplaceSubVecDS  a (b:Vector<_>) = let arrB = b.Values  in GU.inplace_mapiVecGU  (fun i x   -> x - arrB.[i]) a
+        let inplace_subRowVecDS a (b:RowVector<_>) = let arrB = b.Values in GU.inplace_mapiRowVecGU (fun i x   -> x - arrB.[i]) a
+        let inplaceCptMulDenseMatrixDS  a (b:DenseMatrix<_>) = let arrB = b.Values  in GU.inplace_mapiDenseMatrixGU  (fun i j x -> x * GU.getArray2D arrB i j) a
+        let inplaceCptMulVecDS  a (b:Vector<_>) = let arrB = b.Values  in GU.inplace_mapiVecGU  (fun i x   -> x * arrB.[i]) a
+        let inplace_cptMulRowVecDS a (b:RowVector<_>) = let arrB = b.Values in GU.inplace_mapiRowVecGU (fun i x   -> x * arrB.[i]) a
+        let inplaceScaleDenseMatrixDS  (a:float) b = GU.inplace_mapiDenseMatrixGU  (fun _ _ x -> a * x) b
+        let inplaceScaleVecDS  (a:float) b = GU.inplace_mapiVecGU  (fun _ x   -> a * x) b
+        let inplace_scaleRowVecDS (a:float) b = GU.inplace_mapiRowVecGU (fun _ x   -> a * x) b
+
+
+
+    /// Generic operations that, when used on floating point types, use the specialized versions in DoubleImpl
+    module SpecializedGenericImpl = 
+
+        open Microsoft.FSharp.Math.Instances
+        open Microsoft.FSharp.Math.GlobalAssociations
+
+        module GU = GenericImpl
+        module DS = DoubleImpl
+
+          
+        type smatrix = SparseMatrix<float>
+        type dmatrix = DenseMatrix<float>
+        type vector = Vector<float>
+        type rowvec = RowVector<float>
+        let inline dense x = DenseRepr(x)
+        let inline sparse x = SparseRepr(x)
+        let inline createMx  ops rows columns f = GU.createDenseMatrixGU ops rows columns f |> dense
+        let inline createVx  ops m f   = GU.createVecGU ops m f
+        let inline createRVx ops m f   = GU.createRowVecGU ops m f
+
+        let nonZeroEntriesM a   = 
+            match a with 
+            | DenseRepr a -> GU.nonzeroEntriesDenseMatrixGU a 
+            | SparseRepr a -> GU.nonZeroEntriesSparseMatrixGU a 
+
+        /// Merge two sorted sequences
+        let mergeSorted cf (s1: seq<'T>) (s2: seq<'b>) =
+            seq { use e1 = s1.GetEnumerator()
+                  use e2 = s2.GetEnumerator()
+                  let havee1 = ref (e1.MoveNext())
+                  let havee2 = ref (e2.MoveNext())
+                  while !havee1 || !havee2 do
+                    if !havee1 && !havee2 then
+                        let v1 = e1.Current
+                        let v2 = e2.Current
+                        let c = cf v1 v2 
+                        if c < 0 then 
+                            do havee1 := e1.MoveNext()
+                            yield Some(v1),None
+                        elif c = 0 then
+                            do havee1 := e1.MoveNext()
+                            do havee2 := e2.MoveNext()
+                            yield Some(v1),Some(v2)
+                        else 
+                            do havee2 := e2.MoveNext()
+                            yield (None,Some(v2))
+                    elif !havee1 then 
+                        let v1 = e1.Current
+                        do havee1 := e1.MoveNext()
+                        yield (Some(v1),None)
+                    else 
+                        let v2 = e2.Current
+                        do havee2 := e2.MoveNext()
+                        yield (None,Some(v2)) }
+
+        /// Non-zero entries from two sequences
+        let mergedNonZeroEntriesM  (a:Matrix<_>) (b:Matrix<_>) = 
+            let ops = a.ElementOps 
+            let zero = ops.Zero
+            mergeSorted (fun (i1,j1,_) (i2,j2,_) -> let c = compare i1 i2 in if c <> 0 then c else compare j1 j2) (nonZeroEntriesM a) (nonZeroEntriesM b)
+            |> Seq.map (function | Some(i,j,v1),Some(_,_,v2) -> (v1,v2)
+                                 | Some(i,j,v1),None         -> (v1,zero)
+                                 | None,        Some(i,j,v2) -> (zero,v2)
+                                 | None,        None          -> failwith "unreachable")
+
+
+        
+        // Creation
+        let listM    xss : Matrix<'T>    = GU.listDenseMatrixGU opsdata<'T> xss |> dense
+        let listV    xss : Vector<'T>    = GU.listVecGU         opsdata<'T> xss
+        let listRV   xss : RowVector<'T> = GU.listRowVecGU      opsdata<'T> xss
+
+        let arrayM    xss : Matrix<'T>    = GU.mkDenseMatrixGU  opsdata<'T> (Array2D.copy xss) |> dense
+        let arrayV    xss : Vector<'T>    = GU.mkVecGU          opsdata<'T> (Array.copy xss)
+        let arrayRV   xss : RowVector<'T> = GU.mkRowVecGU       opsdata<'T> (Array.copy xss)
+
+        let seqM    xss : Matrix<'T>    = GU.seqDenseMatrixGU   opsdata<'T> xss |> dense
+        let seqV    xss : Vector<'T>    = GU.seqVecGU           opsdata<'T> xss
+        let seqRV   xss : RowVector<'T> = GU.seqRowVecGU        opsdata<'T> xss
+
+        let initM  m n f : Matrix<'T>    = GU.createDenseMatrixGU opsdata<'T> m n f |> dense
+        let initRV m   f : RowVector<'T> = GU.createRowVecGU      opsdata<'T> m   f
+        let initV  m   f : Vector<'T>    = GU.createVecGU         opsdata<'T> m   f
+
+        let constM  m n x : Matrix<'T>    = GU.createConstDenseMatrixGU opsdata<'T> m n x |> dense
+        let constRV m   x : RowVector<'T> = GU.createConstRowVecGU      opsdata<'T> m   x
+        let constV  m   x : Vector<'T>    = GU.createConstVecGU         opsdata<'T> m   x
+
+        let inline inplaceAssignM  f a = 
+            match a with 
+            | SparseRepr _ -> sparseNotMutable()
+            | DenseRepr a -> GU.assignDenseMatrixGU  f a
+        let inline assignV  f a = GU.assignVecGU  f a
+
+        let coerce2 x = unbox(box(x))
+        let loosenDM (x: dmatrix) : DenseMatrix<_>  = coerce2 x
+        let loosenSM (x: smatrix) : SparseMatrix<_> = coerce2 x
+        let loosenV  (x: vector)  : Vector<_>       = coerce2 x
+        let loosenRV (x: rowvec)  : RowVector<_>    = coerce2 x
+        let loosenF  (x: float)   : 'T              = coerce2 x
+
+        let tightenDM (x: DenseMatrix<_>)  : dmatrix = coerce2 x
+        let tightenSM (x: SparseMatrix<_>) : smatrix = coerce2 x
+        let tightenV  (x: Vector<_>)       : vector  = coerce2 x
+        let tightenRV (x: RowVector<_>)    : rowvec  = coerce2 x
+        let tightenF  (x: 'T)              : float   = coerce2 x
+
+        let zeroM m n = 
+            let arr = GU.createArray2D m n
+            // This is quite performance critical
+            // Avoid assigining zeros into the array
+            match box arr with 
+            | :? (float[,])   as arr -> GU.mkDenseMatrixGU DS.FloatOps arr |> loosenDM |> dense
+            | _ -> 
+            GU.zeroizeDenseMatrixGUA arr m n  |> dense
+
+        let zeroV m  : Vector<'T> = 
+            let arr = GU.createArray m 
+            // Avoid assigining zeros into the array
+            match box (arr: 'T[]) with 
+            | :? (float[])   as arr -> GU.mkVecGU DS.FloatOps arr |> loosenV
+            | _ -> 
+            GU.zeroizeVecGUA arr m
+
+        let zeroRV m  : RowVector<'T> = 
+            let arr = GU.createArray m 
+            // Avoid assigining zeros into the array
+            match box (arr: 'T[]) with 
+            | :? (float[])   as arr -> GU.mkRowVecGU DS.FloatOps arr |> loosenRV
+            | _ -> 
+            GU.zeroizeRowVecGUA arr m
+            
+        let initNumericM m n f   = 
+            let arr = GU.createArray2D m n 
+            let opsData = opsdata<'T> 
+            let ops = GU.opsOfOpsData opsData 
+            GU.assignArray2D m n (f ops) arr;
+            GU.mkDenseMatrixGU opsData arr |> dense
+
+        let identityM m   = 
+            let arr = GU.createArray2D m m 
+            // This is quite performance critical
+            // Avoid assigining zeros into the array
+            match box arr with 
+            | :? (float[,])   as arr -> 
+                for i = 0 to m - 1 do 
+                   arr.[i,i] <- 1.0 
+                GU.mkDenseMatrixGU DS.FloatOps arr |> loosenDM |> dense
+            | _ -> 
+            let opsData = opsdata<'T> 
+            let ops = GU.opsOfOpsData opsData 
+            let zero = ops.Zero 
+            let one = ops.One 
+            GU.assignArray2D m m (fun i j -> if i = j then one else zero) arr;
+            GU.mkDenseMatrixGU opsData arr |> dense
+
+        let createNumericV m f  : Vector<'T> = 
+            let arr = GU.createArray m 
+            let opsData = opsdata<'T> 
+            let ops = GU.opsOfOpsData opsData 
+            GU.assignArray m (f ops) arr;
+            GU.mkVecGU opsData arr
+            
+        let scalarM   x = constM 1 1 x 
+        let scalarRV  x = constRV 1 x 
+        let scalarV   x = constV 1 x 
+
+        let diagnM (v:Vector<_>) n = 
+            let ops = v.ElementOps
+            let zero = ops.Zero 
+            let nV = v.NumRows + (if n < 0 then -n else n) 
+            createMx v.OpsData nV nV (fun i j -> if i+n=j then v.[i] else zero)
+
+        let diagM v = diagnM v 0
+
+        let constDiagM  n x : Matrix<'T> = 
+            let opsData = opsdata<'T> 
+            let ops = GU.opsOfOpsData opsData 
+            let zero = ops.Zero 
+            createMx opsData n n (fun i j -> if i=j then x else zero) 
+
+        // Note: we drop sparseness on pointwise multiplication of sparse and dense.
+        let inline binaryOpM opDenseDS opDenseGU opSparseDS opSparseMatrixGU a b = 
+            match a,b with 
+            | DenseRepr a,DenseRepr b -> 
+                match box a with 
+                | (:? dmatrix as a) -> opDenseDS   a (tightenDM b) |> loosenDM |> dense
+                | _                 -> opDenseGU a b                           |> dense
+            | SparseRepr a,SparseRepr b ->
+                match box a with 
+                | (:? smatrix as a) -> opSparseDS a (tightenSM b) |> loosenSM |> sparse
+                | _                 -> opSparseMatrixGU a b                         |> sparse
+            | SparseRepr a, DenseRepr b     -> opDenseGU (GU.toDenseSparseMatrixGU a) b         |> dense
+            | DenseRepr  a, SparseRepr b    -> opDenseGU a (GU.toDenseSparseMatrixGU b)         |> dense
+
+        let inline unaryOpM opDenseDS opDenseGU opSparseDS opSparseMatrixGU  b = 
+            match b with 
+            | DenseRepr b -> 
+                match box b with 
+                | (:? dmatrix as b)  -> opDenseDS b |> loosenDM |> dense
+                | _                  -> opDenseGU b             |> dense
+            | SparseRepr b ->             
+                match box b with 
+                | (:? smatrix as b) -> opSparseDS b |> loosenSM |> sparse
+                | _                 -> opSparseMatrixGU b             |> sparse
+
+        let inline floatUnaryOpM opDenseDS opDenseGU opSparseDS opSparseMatrixGU  b = 
+            match b with 
+            | DenseRepr b -> 
+                match box b with 
+                | (:? dmatrix as b)  -> opDenseDS b |> loosenF
+                | _                  -> opDenseGU b             
+            | SparseRepr b ->             
+                match box b with 
+                | (:? smatrix as b) -> opSparseDS b |> loosenF 
+                | _                 -> opSparseMatrixGU b             
+
+        let addM a b = binaryOpM DS.addDenseMatrixDS GU.addDenseMatrixGU DS.addSparseDS GU.addSparseMatrixGU a b
+        let subM a b = binaryOpM DS.subDenseMatrixDS GU.subDenseMatrixGU DS.subSparseDS GU.subSparseMatrixGU a b
+        let mulM a b = binaryOpM DS.mulDenseMatrixDS GU.genericMulDenseMatrix DS.mulSparseDS GU.mulSparseMatrixGU a b
+        let cptMulM a b = binaryOpM DS.cptMulDenseMatrixDS GU.cptMulDenseMatrixGU DS.cptMulSparseDS GU.cptMulSparseMatrixGU a b
+        let cptMaxM a b = binaryOpM DS.cptMaxDenseMatrixDS GU.cptMaxDenseMatrixGU DS.cptMaxSparseDS GU.cptMaxSparseMatrixGU a b
+        let cptMinM a b = binaryOpM DS.cptMinDenseMatrixDS GU.cptMinDenseMatrixGU DS.cptMinSparseDS GU.cptMinSparseMatrixGU a b
+
+        let addRV a b = 
+            match box a with 
+            | (:? rowvec as a) -> DS.addRowVecDS a (tightenRV b) |> loosenRV
+            | _                -> GU.addRowVecGU a b
+
+        let addV a b = 
+            match box a with 
+            | (:? vector as a) -> DS.addVecDS a (tightenV b) |> loosenV
+            | _                -> GU.addVecGU a b
+
+        let subRV a b = 
+            match box a with 
+            | (:? rowvec as a) -> DS.subRowVecDS   a (tightenRV b) |> loosenRV
+            | _                -> GU.subRowVecGU a b
+
+        let subV a b = 
+            match box a with 
+            | (:? vector as a) -> DS.subVecDS   a (tightenV b) |> loosenV
+            | _                -> GU.subVecGU a b
+
+        let mulRVM a b = 
+            match b with 
+            | DenseRepr b -> 
+                match box a with 
+                | (:? rowvec as a) -> DS.mulRowVecDenseMatrixDS   a (tightenDM b) |> loosenRV
+                | _                -> GU.mulRowVecDenseMatrixGU a b
+            | SparseRepr b -> GU.mulRVSparseMatrixGU a b
+
+        let mulMV a b = 
+            match a with 
+            | DenseRepr a -> 
+                match box a with 
+                | (:? dmatrix as a) -> DS.mulDenseMatrixVecDS   a (tightenV b) |> loosenV
+                | _                 -> GU.mulDenseMatrixVecGU a b
+            | SparseRepr a -> GU.mulSparseVecGU a b 
+
+        let mulRVV a b = 
+            match box a with 
+            | (:? rowvec as a) -> DS.mulRowVecVecDS   a (tightenV b) |> loosenF
+            | _                -> GU.mulRowVecVecGU a b
+
+        let mulVRV a b = 
+            match box a with 
+            | (:? vector as a) -> DS.mulVecRowVecDS   a (tightenRV b) |> loosenDM |> dense
+            | _                -> GU.mulVecRowVecGU a b |> dense
+
+        let cptMulRV a b = 
+            match box a with 
+            | (:? rowvec as a) -> DS.cptMulRowVecDS   a (tightenRV b) |> loosenRV
+            | _                -> GU.cptMulRowVecGU a b
+
+        let cptMulV a b = 
+            match box a with 
+            | (:? vector as a) -> DS.cptMulVecDS   a (tightenV b) |> loosenV
+            | _                -> GU.cptMulVecGU a b
+
+        let cptMaxV a b = 
+            match box a with 
+            | (:? vector as a) -> DS.cptMaxVecDS   a (tightenV b) |> loosenV
+            | _                -> GU.cptMaxVecGU a b
+
+        let cptMinV a b = 
+            match box a with 
+            | (:? vector as a) -> DS.cptMinVecDS   a (tightenV b) |> loosenV
+            | _                -> GU.cptMinVecGU a b
+
+        let scaleM a b = unaryOpM (fun b -> DS.scaleDenseMatrixDS (tightenF a) b) (GU.scaleDenseMatrixGU a)
+                                  (fun b -> DS.scaleSparseDS (tightenF a) b) (GU.scaleSparseMatrixGU a) b
+
+        let scaleRV a b = 
+            match box b with 
+            | (:? rowvec as b)  -> DS.scaleRowVecDS (tightenF a) b |> loosenRV 
+            | _                 -> GU.scaleRowVecGU a b
+
+        let scaleV a b = 
+            match box b with 
+            | (:? vector as b)  -> DS.scaleVecDS (tightenF a) b |> loosenV
+            | _                 -> GU.scaleVecGU a b
+
+        let dotM a b = 
+            match a,b with 
+            | DenseRepr a,DenseRepr b -> 
+                match box b with 
+                | (:? dmatrix as b)  -> DS.dotDenseMatrixDS   (tightenDM a) b |> loosenF
+                | _                  -> GU.dotDenseMatrixGU a b
+            | _ ->  
+                let ops = a.ElementOps 
+                mergedNonZeroEntriesM a b |> Seq.fold (fun z (va,vb) -> GU.add ops z (GU.mul ops va vb)) ops.Zero 
+
+        let dotV a b = 
+            match box b with 
+            | (:? vector as b)  -> DS.dotVecDS   (tightenV a) b |> loosenF
+            | _                 -> GU.dotVecGU a b
+
+        let negM a = unaryOpM DS.negDenseMatrixDS GU.negDenseMatrixGU DS.negSparseDS GU.negSparseMatrixGU a
+
+        let negRV a = 
+            match box a with 
+            | (:? rowvec as a) -> DS.negRowVecDS a |> loosenRV
+            | _               ->  GU.negRowVecGU a
+
+        let negV a = 
+            match box a with 
+            | (:? vector as a) -> DS.negVecDS a |> loosenV
+            | _               ->  GU.negVecGU a
+
+        let traceMGU (a:Matrix<_>) =
+            let nA = a.NumCols  
+            let mA = a.NumRows 
+            if nA<>mA then invalidArg "a" "expected a square matrix";
+            let ops = a.ElementOps 
+            (0,nA-1) |> GU.sumRGU ops (fun i -> a.[i,i]) 
+
+        let traceM a = floatUnaryOpM DS.traceDenseMatrixDS (dense >> traceMGU) (sparse >> traceMGU) (sparse >> traceMGU) a
+        let sumM a = floatUnaryOpM DS.sumDenseMatrixDS GU.sumDenseMatrixGU GU.sumSparseMatrixGU GU.sumSparseMatrixGU a
+        let prodM a = floatUnaryOpM DS.prodDenseMatrixDS GU.prodDenseMatrixGU GU.prodSparseMatrixGU GU.prodSparseMatrixGU a
+        let normM a = floatUnaryOpM DS.normDenseMatrixDS GU.normDenseMatrixGU GU.normSparseMatrixGU GU.normSparseMatrixGU a
+
+        let opsM a = 
+            match a with 
+            | DenseRepr a -> a.OpsData 
+            | SparseRepr a -> a.OpsData 
+        
+        let transM a = 
+            match a with 
+            | DenseRepr a -> 
+                // rows of transposed matrix = columns of original matrix and vice versa
+                createMx a.OpsData a.NumCols a.NumRows (fun i j -> a.[j,i])
+            | SparseRepr a -> 
+                a |> GU.nonZeroEntriesSparseMatrixGU  |> Seq.map (fun (i,j,v) -> (j,i,v)) |> GU.initSparseMatrixGU a.NumCols a.NumRows a.OpsData |> sparse
+        
+        let permuteRows (p: permutation) a =
+            match a with
+            | DenseRepr a ->
+                createMx a.OpsData a.NumRows a.NumCols (fun i j -> a.[p i,j])
+            | SparseRepr a ->
+                a |> GU.nonZeroEntriesSparseMatrixGU  |> Seq.map (fun (i,j,v) -> (p i,j,v)) |> GU.initSparseMatrixGU a.NumCols a.NumRows a.OpsData |> sparse
+
+        let permuteColumns (p: permutation) a =
+            match a with
+            | DenseRepr a ->
+                createMx a.OpsData a.NumRows a.NumCols (fun i j -> a.[i,p j])
+            | SparseRepr a ->
+                a |> GU.nonZeroEntriesSparseMatrixGU  |> Seq.map (fun (i,j,v) -> (i,p j,v)) |> GU.initSparseMatrixGU a.NumCols a.NumRows a.OpsData |> sparse
+
+        let transRV (a:RowVector<_>) = 
+            createVx a.OpsData  a.NumCols (fun i -> a.[i])
+
+        let transV (a:Vector<_>)  = 
+            createRVx a.OpsData a.NumRows (fun i -> a.[i])
+
+        let inplaceAddM a b = 
+            match a,b with 
+            | DenseRepr a,DenseRepr b -> 
+                match box a with 
+                | (:? dmatrix as a) -> DS.inplaceAddDenseMatrixDS   a (tightenDM b)
+                | _                 -> GU.inplaceAddDenseMatrixGU a b
+            | _ -> sparseNotMutable()
+
+        let inplaceAddV a b = 
+            match box a with 
+            | (:? vector as a) -> DS.inplaceAddVecDS   a (tightenV b)
+            | _                -> GU.inplaceAddVecGU a b
+
+        let inplaceSubM a b = 
+            match a,b with 
+            | DenseRepr a,DenseRepr b -> 
+                match box a with 
+                | (:? dmatrix as a) -> DS.inplaceSubDenseMatrixDS   a (tightenDM b)
+                | _                -> GU.inplaceSubDenseMatrixGU a b
+            | _ -> sparseNotMutable()
+
+        let inplaceSubV a b = 
+            match box a with 
+            | (:? vector as a) -> DS.inplaceSubVecDS   a (tightenV b)
+            | _                -> GU.inplaceSubVecGU a b
+
+
+        let inplaceCptMulM a b = 
+            match a,b with 
+            | DenseRepr a,DenseRepr b -> 
+                match box a with 
+                | (:? dmatrix as a) -> DS.inplaceCptMulDenseMatrixDS   a (tightenDM b)
+                | _                -> GU.inplaceCptMulDenseMatrixGU a b
+            | _ -> sparseNotMutable()
+
+        let inplaceCptMulV a b = 
+            match box a with 
+            | (:? vector as a) -> DS.inplaceCptMulVecDS   a (tightenV b)
+            | _                -> GU.inplaceCptMulVecGU a b
+
+        let inplaceScaleM a b = 
+            match b with 
+            | DenseRepr b -> 
+                match box b with 
+                | (:? dmatrix as b)  -> DS.inplaceScaleDenseMatrixDS   (tightenF a) b
+                | _                 -> GU.inplaceScaleDenseMatrixGU a b
+            | _ -> sparseNotMutable()
+
+        let inplaceScaleV a b = 
+            match box b with 
+            | (:? vector as b)  -> DS.inplaceScaleVecDS   (tightenF a) b
+            | _                 -> GU.inplaceScaleVecGU a b
+
+        let existsM  f a = 
+            match a with 
+            | SparseRepr _ -> sparseNYI() // note: martin says "run f on a token element if it's not full"
+            | DenseRepr a -> GU.existsiDenseMatrixGU  (fun _ _ -> f) a
+
+        let existsV  f a = GU.existsiVecGU  (fun _ -> f) a
+
+        let forallM  f a = 
+            match a with 
+            | SparseRepr _ -> sparseNYI()
+            | DenseRepr a -> GU.foralliDenseMatrixGU  (fun _ _ -> f) a
+
+        let forallV  f a = GU.foralliVecGU  (fun _ -> f) a
+
+        let existsiM  f a = 
+            match a with 
+            | SparseRepr _ -> sparseNYI()
+            | DenseRepr a -> GU.existsiDenseMatrixGU  f a
+
+        let existsiV  f a = GU.existsiVecGU  f a
+
+        let foralliM  f a = 
+            match a with 
+            | SparseRepr _ -> sparseNYI()
+            | DenseRepr a -> GU.foralliDenseMatrixGU  f a
+
+        let foralliV  f a = GU.foralliVecGU  f a
+
+        let mapM  f a = 
+            match a with 
+            | SparseRepr _ -> sparseNYI()
+            | DenseRepr a -> DenseRepr(GU.mapDenseMatrixGU f a)
+
+        let mapV  f a = GU.mapVecGU f a
+
+        let copyM  a = 
+            match a with 
+            | SparseRepr a -> SparseRepr (GU.copySparseGU a)
+            | DenseRepr a -> DenseRepr (GU.copyDenseMatrixGU a)
+
+        let copyV  a = GU.copyVecGU a
+
+        let copyRV  a = GU.copyRowVecGU a
+
+        let mapiM  f a = 
+            match a with 
+            | SparseRepr _ -> sparseNYI()
+            | DenseRepr a -> DenseRepr (GU.mapiDenseMatrixGU f a)
+
+        let mapiV  f a = GU.mapiVecGU f a
+        let permuteV p a = GU.permuteVecGU p a
+        let permuteRV p a = GU.permuteRowVecGU p a
+
+        let mapiRV  f a = GU.mapiRowVecGU f a
+
+        let toDenseM a = 
+            match a with 
+            | SparseRepr a -> GU.toDenseSparseMatrixGU a |> dense
+            | DenseRepr _ -> a
+
+        let initSparseM i j x : Matrix<'T> = 
+            let opsData = opsdata<'T> 
+            GU.initSparseMatrixGU i j opsData x |> sparse
+          
+        let initDenseM i j x : Matrix<'T> = 
+            let r = zeroM i j
+            x |> Seq.iter (fun (i,j,v) -> r.[i,j] <- v);
+            r
+
+        let getDiagnM (a:Matrix<_>) n =
+            let nA = a.NumCols 
+            let mA = a.NumRows
+            if nA<>mA then invalidArg "a" "expected a square matrix";
+            let ni = if n < 0 then -n else 0 
+            let nj = if n > 0 then  n else 0 
+            GU.createVecGU (opsM a) (max (nA-abs(n)) 0) (fun i -> a.[i+ni,i+nj]) 
+
+        let getDiagM  a = getDiagnM a 0
+
+        let inline inplace_mapiM  f a = 
+            match a with 
+            | SparseRepr _ -> sparseNotMutable()
+            | DenseRepr a -> GU.inplace_mapiDenseMatrixGU f a
+
+        let inline inplace_mapiV  f a = GU.inplace_mapiVecGU f a
+        
+        let inline foldM  f z a = 
+            match a with 
+            | SparseRepr _ -> sparseNYI()
+            | DenseRepr a -> GU.foldDenseMatrixGU f z a
+
+        let inline foldV  f z a = GU.foldVecGU f z a
+
+        let inline foldiM  f z a = 
+            match a with 
+            | SparseRepr _ -> sparseNYI()
+            | DenseRepr a -> GU.foldiDenseMatrixGU f z a
+
+        let inline foldiV  f z a = GU.foldiVecGU f z a
+
+        let compareM (comp: IComparer) (a:Matrix<'T>) (b:Matrix<'T>) = 
+            let nA = a.NumCols 
+            let mA = a.NumRows 
+            let nB = b.NumCols 
+            let mB = b.NumRows 
+            let c = compare mA mB 
+            if c <> 0 then c else
+            let c = compare nA nB 
+            if c <> 0 then c else
+            match a,b with 
+            | DenseRepr a, DenseRepr b -> 
+              let rec go2 i j = 
+                 if j < nA then 
+                   let c = comp.Compare( a.[i,j], b.[i,j])
+                   if c <> 0 then c else 
+                   go2 i (j+1) 
+                 else 0 
+              let rec go1 i = 
+                 if i < mA then 
+                   let c = go2 i 0 
+                   if c <> 0 then c 
+                   else go1 (i+1) 
+                 else 0 
+              go1 0
+            | _ -> 
+              match (mergedNonZeroEntriesM a b |> Seq.tryPick (fun (v1,v2) -> let c = comp.Compare(v1,v2) in if c = 0 then None else Some(c))) with
+              | None -> 0
+              | Some(c) -> c
+             
+        let equalsM (comp: IEqualityComparer) (a:Matrix<'T>) (b:Matrix<'T>) = 
+            let nA = a.NumCols 
+            let mA = a.NumRows 
+            let nB = b.NumCols 
+            let mB = b.NumRows 
+            (mA = mB ) && (nA = nB) && 
+            match a,b with 
+            | DenseRepr a, DenseRepr b -> 
+                let rec go2 i j =  j >= nA || (comp.Equals( a.[i,j], b.[i,j]) && go2 i (j+1) )
+                let rec go1 i = i >= mA || (go2 i 0  && go1 (i+1))
+                go1 0
+            | _ -> 
+                mergedNonZeroEntriesM a b |> Seq.forall (fun (v1,v2) -> comp.Equals(v1,v2))
+             
+
+        let compareV (comp: IComparer) (a:Vector<'T>) (b:Vector<'T>) = 
+            let mA = a.NumRows
+            let mB = b.NumRows 
+            let c = compare mA mB 
+            if c <> 0 then c else
+            let rec go2 j = 
+               if j < mA then 
+                 let c = comp.Compare(a.[j],b.[j])
+                 if c <> 0 then c else go2 (j+1) 
+               else 0 
+            go2 0
+
+        let equalsV (comp: IEqualityComparer) (a:Vector<'T>) (b:Vector<'T>) = 
+            let mA = a.NumRows
+            let mB = b.NumRows 
+            (mA = mB) && 
+            let rec go2 j = (j >= mA) || (comp.Equals(a.[j],b.[j]) && go2 (j+1))
+            go2 0
+
+        let equalsRV (comp: IEqualityComparer) (a:RowVector<'T>) (b:RowVector<'T>) = 
+            let mA = a.NumCols 
+            let mB = b.NumCols 
+            (mA = mB) && 
+            let rec go2 j = (j >= mA) || (comp.Equals(a.[j],b.[j]) && go2 (j+1))
+            go2 0
+
+        let compareRV (comp: IComparer) (a:RowVector<'T>) (b:RowVector<'T>) = 
+            let mA = a.NumCols 
+            let mB = b.NumCols 
+            let c = compare mA mB 
+            if c <> 0 then c else
+            let rec go2 j = 
+               if j < mA then 
+                 let c = comp.Compare(a.[j],b.[j])
+                 if c <> 0 then c else go2 (j+1) 
+               else 0 
+            go2 0
+
+        let inline combineHash x y = (x <<< 1) + y + 631 
+
+        let hashM (comp:IEqualityComparer) (a:Matrix<_>) = 
+            let nA = a.NumCols 
+            let mA = a.NumRows 
+            let acc = hash mA + hash nA
+            a |> nonZeroEntriesM |> Seq.truncate 20 |> Seq.fold (fun z v -> combineHash z (comp.GetHashCode v)) acc
+          
+        let hashV (comp:IEqualityComparer) (a:Vector<_>) = 
+            let mA = a.NumRows 
+            hash mA +
+            (let mutable c = 0 
+             for i = 0 to mA - 1 do
+                 c <- combineHash c (comp.GetHashCode a.[i])
+             c)
+          
+        let hashRV (comp:IEqualityComparer) (a:RowVector<_>) = 
+            let mA = a.NumCols 
+            hash mA +
+            (let mutable c = 0 
+             for i = 0 to mA - 1 do
+                 c <- combineHash c (comp.GetHashCode a.[i])
+             c)
+          
+        type range = int * int
+
+        let startR ((a,_) : range)   = a
+        let countR ((a,b) : range)   = (b-a)+1
+        let idxR    ((a,_) : range) i = a+i
+        let inR    ((a,b) : range) i = a <= i && i <= b
+        
+        let getRowM  (a:Matrix<_>) i = createRVx (opsM a) a.NumCols (fun j -> a.[i,j])
+        let selColM  (a:Matrix<_>) j = createVx (opsM a) a.NumRows (fun i -> a.[i,j]) 
+        let getRegionV  (a:Vector<_>)    r      = createVx a.OpsData (countR r) (fun i -> a.[idxR r i]) 
+        let getRegionRV (a:RowVector<_>) r      = createRVx a.OpsData (countR r) (fun i -> a.[idxR r i]) 
+
+        let getRegionM  a ri rj    = 
+            match a with 
+            | DenseRepr a -> createMx a.OpsData (countR ri) (countR rj) (fun i j -> a.[idxR ri i, idxR rj j]) 
+            | _ -> nonZeroEntriesM a 
+                   |> Seq.filter (fun (i,j,_) -> inR ri i && inR rj j) 
+                   |> Seq.map (fun (i,j,v) -> (i-startR ri,j-startR rj,v)) 
+                   |> initSparseM (countR ri) (countR rj)
+
+        let getColsM (a:Matrix<_>) rj         = getRegionM a (0,a.NumRows - 1) rj
+        let getRowsM (a:Matrix<_>) ri         = getRegionM a ri (0,a.NumCols - 1)
+
+        let rowvecM (x:RowVector<_>) = initM 1         x.NumCols (fun _ j -> x.[j]) 
+        let vectorM (x:Vector<_>) = initM x.NumRows  1         (fun i _ -> x.[i])  
+        let toVectorM x = selColM x 0 
+        let toRowVectorM x = getRowM x 0 
+        let toScalarM (x:Matrix<_>) = x.[0,0]
+
+
+
+//----------------------------------------------------------------------------
+// type Matrix<'T> augmentation
+//--------------------------------------------------------------------------*)
+
+    type Matrix<'T> with
+        static member ( +  )(a: Matrix<'T>,b) = SpecializedGenericImpl.addM a b
+        static member ( -  )(a: Matrix<'T>,b) = SpecializedGenericImpl.subM a b
+        static member ( *  )(a: Matrix<'T>,b) = SpecializedGenericImpl.mulM a b
+        static member ( *  )(a: Matrix<'T>,b : Vector<'T>) = SpecializedGenericImpl.mulMV a b
+
+        static member ( * )((m: Matrix<'T>),k : 'T) = SpecializedGenericImpl.scaleM k m
+
+        static member ( .* )(a: Matrix<'T>,b) = SpecializedGenericImpl.cptMulM a b
+        static member ( * )(k,m: Matrix<'T>) = SpecializedGenericImpl.scaleM k m
+        static member ( ~- )(m: Matrix<'T>)     = SpecializedGenericImpl.negM m
+        static member ( ~+ )(m: Matrix<'T>)     = m
+
+        member m.GetSlice (start1,finish1,start2,finish2) = 
+            let start1 = match start1 with None -> 0 | Some v -> v 
+            let finish1 = match finish1 with None -> m.NumRows - 1 | Some v -> v 
+            let start2 = match start2 with None -> 0 | Some v -> v 
+            let finish2 = match finish2 with None -> m.NumCols - 1 | Some v -> v 
+            SpecializedGenericImpl.getRegionM m (start1,finish1) (start2,finish2)
+
+        member m.SetSlice (start1,finish1,start2,finish2,vs:Matrix<_>) = 
+            let start1 = match start1 with None -> 0 | Some v -> v 
+            let finish1 = match finish1 with None -> m.NumRows - 1 | Some v -> v 
+            let start2 = match start2 with None -> 0 | Some v -> v 
+            let finish2 = match finish2 with None -> m.NumCols - 1 | Some v -> v 
+            for i = start1 to finish1  do 
+               for j = start2 to finish2 do
+                   m.[i,j] <- vs.[i-start1,j-start2]
+
+        override m.ToString() = 
+           match m with 
+           | DenseRepr m -> GenericImpl.showDenseMatrixGU m
+           | SparseRepr _ -> "<sparse>"
+
+        member m.DebugDisplay = 
+           let txt = 
+               match m with 
+               | DenseRepr m -> GenericImpl.debugShowDenseMatrixGU m
+               | SparseRepr _ -> "<sparse>"
+           new System.Text.StringBuilder(txt)  // return an object with a ToString with the right value, rather than a string. (strings get shown using quotes)
+
+        member m.StructuredDisplayAsArray =  
+            let rec layout m = 
+                match m with 
+                | DenseRepr _ -> box (Array2D.init m.NumRows m.NumCols (fun i j -> m.[i,j]))
+                | SparseRepr _ -> (if m.NumRows < 20 && m.NumCols < 20 then layout (SpecializedGenericImpl.toDenseM m) else box(SpecializedGenericImpl.nonZeroEntriesM m))
+            layout m
+        member m.Dimensions = m.NumRows,m.NumCols
+
+        member m.Transpose = SpecializedGenericImpl.transM m
+        member m.PermuteRows (p: permutation) : Matrix<'T> = SpecializedGenericImpl.permuteRows p m
+        member m.PermuteColumns (p: permutation) : Matrix<'T> = SpecializedGenericImpl.permuteColumns p m
+
+        interface IEnumerable<'T> with 
+            member m.GetEnumerator() = 
+               (seq { for i in 0 .. m.NumRows-1 do
+                        for j in 0 .. m.NumCols - 1 do 
+                            yield m.[i,j] }).GetEnumerator()
+
+        interface IEnumerable with 
+            member m.GetEnumerator() =  ((m :> IEnumerable<_>).GetEnumerator() :> IEnumerator)
+                                    
+        interface System.IComparable with 
+             member m.CompareTo(yobj:obj) = SpecializedGenericImpl.compareM LanguagePrimitives.GenericComparer m (yobj :?> Matrix<'T>)
+             
+        interface IStructuralComparable with
+            member m.CompareTo(yobj:obj,comp:System.Collections.IComparer) = SpecializedGenericImpl.compareM comp m (yobj :?> Matrix<'T>)
+            
+        override m.GetHashCode() = SpecializedGenericImpl.hashM LanguagePrimitives.GenericEqualityComparer m 
+        override m.Equals(yobj:obj) = 
+            match yobj with 
+            | :? Matrix<'T> as m2 -> SpecializedGenericImpl.equalsM LanguagePrimitives.GenericEqualityComparer m m2
+            | _ -> false
+        
+        interface IStructuralEquatable with
+            member m.GetHashCode(comp:System.Collections.IEqualityComparer) = SpecializedGenericImpl.hashM comp m
+            member m.Equals(yobj:obj,comp:System.Collections.IEqualityComparer) = 
+                match yobj with 
+                | :? Matrix<'T> as m2 -> SpecializedGenericImpl.equalsM comp m m2
+                | _ -> false
+
+
+//----------------------------------------------------------------------------
+// type Vector<'T> augmentation
+//--------------------------------------------------------------------------*)
+
+    type Vector<'T> with
+        static member ( +  )(a: Vector<'T>,b) = SpecializedGenericImpl.addV a b
+        static member ( -  )(a: Vector<'T>,b) = SpecializedGenericImpl.subV a b
+        static member ( .* )(a: Vector<'T>,b) = SpecializedGenericImpl.cptMulV a b
+        
+        static member ( * )(k,m: Vector<'T>) = SpecializedGenericImpl.scaleV k m
+        
+        static member ( * )(a: Vector<'T>,b) = SpecializedGenericImpl.mulVRV a b
+        
+        static member ( * )(m: Vector<'T>,k) = SpecializedGenericImpl.scaleV k m
+        
+        static member ( ~- )(m: Vector<'T>)     = SpecializedGenericImpl.negV m
+        static member ( ~+ )(m: Vector<'T>)     = m
+
+        member m.GetSlice (start,finish) = 
+            let start = match start with None -> 0 | Some v -> v 
+            let finish = match finish with None -> m.NumRows - 1 | Some v -> v 
+            SpecializedGenericImpl.getRegionV m (start,finish)
+
+        member m.SetSlice (start,finish,vs:Vector<_>) = 
+            let start = match start with None -> 0 | Some v -> v 
+            let finish = match finish with None -> m.NumRows - 1 | Some v -> v 
+            for i = start to finish  do 
+                   m.[i] <- vs.[i-start]
+
+
+        override m.ToString() = GenericImpl.showVecGU "vector" m
+
+        member m.DebugDisplay = 
+            let txt = GenericImpl.showVecGU "vector" m
+            new System.Text.StringBuilder(txt)  // return an object with a ToString with the right value, rather than a string. (strings get shown using quotes)
+
+        member m.StructuredDisplayAsArray =  Array.init m.NumRows (fun i -> m.[i])
+
+        member m.Details = m.Values
+
+        member m.Transpose = SpecializedGenericImpl.transV m
+        
+        member m.Permute (p:permutation) = SpecializedGenericImpl.permuteV p m
+      
+        interface System.IComparable with 
+             member m.CompareTo(y:obj) = SpecializedGenericImpl.compareV LanguagePrimitives.GenericComparer m (y :?> Vector<'T>)
+        
+        interface IStructuralComparable with
+            member m.CompareTo(y:obj,comp:System.Collections.IComparer) = SpecializedGenericImpl.compareV comp m (y :?> Vector<'T>)
+
+        interface IStructuralEquatable with
+            member x.GetHashCode(comp) = SpecializedGenericImpl.hashV comp x
+            member x.Equals(yobj,comp) = 
+                match yobj with 
+                | :? Vector<'T> as v2 -> SpecializedGenericImpl.equalsV comp x v2
+                | _ -> false
+
+        override x.GetHashCode() = 
+            SpecializedGenericImpl.hashV LanguagePrimitives.GenericEqualityComparer x
+
+        override x.Equals(yobj) = 
+            match yobj with 
+            | :? Vector<'T> as v2 -> SpecializedGenericImpl.equalsV LanguagePrimitives.GenericEqualityComparer x v2
+            | _ -> false
+
+//----------------------------------------------------------------------------
+// type RowVector<'T> augmentation
+//--------------------------------------------------------------------------*)
+
+    type RowVector<'T> with
+        static member ( +  )(a: RowVector<'T>,b) = SpecializedGenericImpl.addRV a b
+        static member ( -  )(a: RowVector<'T>,b) = SpecializedGenericImpl.subRV a b
+        static member ( .* )(a: RowVector<'T>,b) = SpecializedGenericImpl.cptMulRV a b
+        static member ( * )(k,v: RowVector<'T>) = SpecializedGenericImpl.scaleRV k v
+        
+        static member ( * )(a: RowVector<'T>,b: Matrix<'T>) = SpecializedGenericImpl.mulRVM a b
+        static member ( * )(a: RowVector<'T>,b:Vector<'T>) = SpecializedGenericImpl.mulRVV a b
+        static member ( * )(v: RowVector<'T>,k:'T) = SpecializedGenericImpl.scaleRV k v
+        
+        static member ( ~- )(v: RowVector<'T>)     = SpecializedGenericImpl.negRV v
+        static member ( ~+ )(v: RowVector<'T>)     = v
+
+        member m.GetSlice (start,finish) = 
+            let start = match start with None -> 0 | Some v -> v
+            let finish = match finish with None -> m.NumCols - 1 | Some v -> v 
+            SpecializedGenericImpl.getRegionRV m (start,finish)
+
+        member m.SetSlice (start,finish,vs:RowVector<_>) = 
+            let start = match start with None -> 0 | Some v -> v 
+            let finish = match finish with None -> m.NumCols - 1 | Some v -> v 
+            for i = start to finish  do 
+                   m.[i] <- vs.[i-start]
+
+        override m.ToString() = GenericImpl.showRowVecGU "rowvec" m
+
+        member m.DebugDisplay = 
+            let txt = GenericImpl.showRowVecGU "rowvec" m
+            new System.Text.StringBuilder(txt)  // return an object with a ToString with the right value, rather than a string. (strings get shown using quotes)
+
+        member m.StructuredDisplayAsArray =  Array.init m.NumCols (fun i -> m.[i])
+
+        member m.Details = m.Values
+
+        member m.Transpose = SpecializedGenericImpl.transRV m
+        
+        member m.Permute (p:permutation) = SpecializedGenericImpl.permuteRV p m
+      
+        interface System.IComparable with 
+            member m.CompareTo(y) = SpecializedGenericImpl.compareRV LanguagePrimitives.GenericComparer m (y :?> RowVector<'T>)
+        
+        interface IStructuralComparable with
+            member m.CompareTo(y,comp) = SpecializedGenericImpl.compareRV comp m (y :?> RowVector<'T>)
+
+        interface IStructuralEquatable with
+            member x.GetHashCode(comp) = SpecializedGenericImpl.hashRV comp x
+            member x.Equals(yobj,comp) = 
+                match yobj with 
+                | :? RowVector<'T> as rv2 -> SpecializedGenericImpl.equalsRV comp x rv2
+                | _ -> false
+
+        override x.GetHashCode() = 
+            SpecializedGenericImpl.hashRV LanguagePrimitives.GenericEqualityComparer x
+
+        override x.Equals(yobj) = 
+            match yobj with 
+            | :? RowVector<'T> as rv2 -> SpecializedGenericImpl.equalsRV LanguagePrimitives.GenericEqualityComparer x rv2
+            | _ -> false
+
+    type matrix = Matrix<float>
+    type vector = Vector<float>
+    type rowvec = RowVector<float>
+
+    module MRandom = 
+        let seed = 99
+        let randomGen = new System.Random(seed)
+        let float f = randomGen.NextDouble() * f 
+
+
+    [<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+    module Matrix = begin
+        
+        module Generic = begin
+
+            module MS = SpecializedGenericImpl
+
+            // Accessors
+            let get (a:Matrix<_>) i j   = a.[i,j]
+            let set (a:Matrix<_>) i j x = a.[i,j] <- x
+            
+            // Creation
+            let ofList    xss      = MS.listM  xss
+            let ofSeq     xss      = MS.seqM  xss
+            let init  m n f       = MS.initM  m n f
+            let ofArray2D (arr: 'T[,])  : Matrix<'T>       = MS.arrayM arr
+            let toArray2D (m:Matrix<_>) = Array2D.init m.NumRows m.NumCols (fun i j -> get m i j)
+            let initNumeric m n f = MS.initNumericM m n f
+            let zero m n            = MS.zeroM m n
+            let identity m          = MS.identityM m
+            let create  m n x       = MS.constM m n x
+
+            let ofScalar   x        = MS.scalarM x
+
+            let diag v              = MS.diagM v
+            let initDiagonal v      = MS.diagM v
+            let constDiag   n x     = MS.constDiagM n x
+          
+            // Operators
+            let add a b = MS.addM a b
+            let sub a b = MS.subM a b
+            let mul a b = MS.mulM a b
+            let mulRV a b = MS.mulRVM a b
+            let mulV a b = MS.mulMV a b
+            let cptMul a b = MS.cptMulM a b
+            let cptMax a b = MS.cptMaxM a b
+            let cptMin a b = MS.cptMinM a b
+            let scale a b = MS.scaleM a b
+            let dot a b = MS.dotM a b
+            let neg a = MS.negM a 
+            let trace a = MS.traceM a
+            let sum a = MS.sumM a
+            let prod a = MS.prodM a
+            let norm a = MS.normM a
+            let transpose a = MS.transM a
+            let inplaceAdd a b = MS.inplaceAddM a b
+            let inplaceSub a b = MS.inplaceSubM a b
+
+            let exists  f a = MS.existsM  f a
+            let forall  f a = MS.forallM  f a
+            let existsi  f a = MS.existsiM  f a
+            let foralli  f a = MS.foralliM  f a
+            let map  f a = MS.mapM f a
+            let copy a = MS.copyM a
+            let mapi  f a = MS.mapiM f a
+            let getDiagN  a n = MS.getDiagnM a n
+            let getDiag  a = MS.getDiagnM a 0
+            let toDense a = MS.toDenseM a 
+
+            let initDense i j a = MS.initDenseM i j a 
+            let initSparse i j a = MS.initSparseM i j a 
+
+            let fold  f z a = MS.foldM f z a
+            let foldi f z a = MS.foldiM f z a
+          
+            let compare a b = MS.compareM LanguagePrimitives.GenericComparer a b
+            let hash a      = MS.hashM LanguagePrimitives.GenericEqualityComparer a
+            let getRow    a i           = MS.getRowM a i
+            let getCol    a j           = MS.selColM a j
+            let getCols   a i1 i2       = MS.getColsM a (i1,i1+i2-1)
+            let getRows   a j1 j2       = MS.getRowsM a (j1,j1+j2-1)
+            let getRegion a i1 j1 i2 j2 = MS.getRegionM a (i1,i1+i2-1) (j1,j1+j2-1)
+            
+            let ofRowVector x = MS.rowvecM x
+            let ofVector    x = MS.vectorM x
+            let toVector    x = MS.toVectorM x
+            let toRowVector x = MS.toRowVectorM x
+            let toScalar    x = MS.toScalarM x
+
+            let inplace_assign f a  = MS.inplaceAssignM  f a
+            let inplace_cptMul a b = MS.inplaceCptMulM a b
+            let inplace_scale a b = MS.inplaceScaleM a b
+            let inplace_mapi  f a = MS.inplace_mapiM f a
+            let of_rowvec x           = ofRowVector x
+            let of_vector x           = ofVector x
+            let to_vector x           = toVector x
+            let to_rowvec x           = toRowVector x
+            let to_scalar x           = toScalar x
+            let inplace_add a b       = inplaceAdd a b
+            let inplace_sub a b       = inplaceSub a b
+            let of_scalar   x         = ofScalar x
+            let of_list    xss        = ofList xss
+            let of_seq     xss        = ofSeq xss
+            let inline of_array2D arr = ofArray2D arr
+            let inline to_array2D m   = toArray2D m
+            let init_diagonal v       = initDiagonal v
+            let to_dense a            = toDense a
+            let init_dense i j a      = initDense i j a
+            let init_sparse i j a     = initSparse i j a
+            let nonzero_entries a     = MS.nonZeroEntriesM a 
+         
+        end
+
+        module MG = Generic
+        module DS = DoubleImpl
+        module GU = GenericImpl
+        module MS = SpecializedGenericImpl
+
+        // Element type OpsData
+        type elem = float
+
+        // Accessors
+        let get (a:matrix) i j   = MG.get a i j
+        let set (a:matrix) i j x = MG.set a i j x
+        
+        // Creation
+        let init  m n f = DS.initDenseMatrixDS  m n f |> MS.dense 
+        let ofList    xss   = DS.listDenseMatrixDS    xss |> MS.dense
+        let ofSeq     xss   = DS.seqDenseMatrixDS    xss |> MS.dense
+        let diag  (v:vector)   = MG.diag v 
+        let initDiagonal  (v:vector)   = MG.diag v 
+        let constDiag  n x : matrix  = MG.constDiag n x 
+        let create  m n x  = DS.constDenseMatrixDS  m n x |> MS.dense
+        let ofScalar x     = DS.scalarDenseMatrixDS x |> MS.dense
+
+        let ofArray2D arr : matrix = MG.ofArray2D arr
+        let toArray2D (m : matrix) = MG.toArray2D m
+
+        let getDiagN  (a:matrix) n = MG.getDiagN a n
+        let getDiag  (a:matrix) = MG.getDiag a
+
+        // Operators
+        let add (a:matrix) (b:matrix) = MS.addM   a b
+        let sub (a:matrix) (b:matrix) = MS.subM   a b
+        let mul (a:matrix) (b:matrix) = MS.mulM   a b
+        let mulV (a:matrix) (b:vector) = MS.mulMV   a b
+        let mulRV (a:rowvec) (b:matrix) = MS.mulRVM   a b
+        let cptMul (a:matrix) (b:matrix) = MS.cptMulM   a b
+        let cptMax (a:matrix) (b:matrix) = MS.cptMaxM a b
+        let cptMin (a:matrix) (b:matrix) = MS.cptMinM a b
+        let scale a (b:matrix) = MS.scaleM   a b
+        let neg (a:matrix)  = MS.negM a
+        let trace (a:matrix)  = MS.traceM a
+        let transpose  (a:matrix) = MG.transpose a
+        let forall f (a:matrix) = MG.forall f a
+        let exists  f (a:matrix) = MG.exists f a
+        let foralli f (a:matrix) = MG.foralli f a
+        let existsi  f (a:matrix) = MG.existsi f a
+        let map  f (a:matrix) = MG.map f a
+        let copy  (a:matrix) = MG.copy a
+        let mapi  f (a:matrix) : matrix = MG.mapi f a
+        let fold  f z (a:matrix) = MG.fold f z a
+        let foldi  f z (a:matrix) = MG.foldi f z a
+
+        let toDense (a:matrix) = MG.toDense a 
+        let initDense i j a : matrix = MG.initDense i j a 
+        let initSparse i j a : matrix = MG.initSparse i j a 
+        let nonzero_entries (a:matrix) = MG.nonzero_entries a 
+
+        let zero m n  = DS.zeroDenseMatrixDS m n |> MS.dense
+        let identity m  : matrix = MG.identity m 
+        
+        let ones m n  = create m n 1.0
+        
+        let getRow (a:matrix) i      = MG.getRow a i
+        let getCol (a:matrix) j      = MG.getCol a j
+        let getCols (a:matrix) i1 i2    = MG.getCols a i1 i2
+        let getRows (a:matrix) j1 j2    = MG.getRows a j1 j2
+        let getRegion (a:matrix) i1 j1 i2 j2    = MG.getRegion a i1 j1 i2 j2
+
+        let rowRange (a:Matrix<_>) = (0,a.NumRows - 1)
+        let colRange (a:Matrix<_>) = (0,a.NumCols - 1)
+        let wholeRegion a = (colRange a, rowRange a)
+        
+        let foldByRow f (z:Vector<'T>) (a:matrix) = 
+          colRange a |> GU.foldR (fun z j -> MS.mapiV (fun i z -> f z (get a i j)) z) z
+        let foldByCol f (z:RowVector<'T>) (a:matrix) = 
+          rowRange a |> GU.foldR (fun z i -> MS.mapiRV (fun j z -> f z (get a i j)) z) z
+
+        let foldRow f (z:'T) (a:matrix) i = 
+          colRange a |> GU.foldR (fun (z:'T) j -> f z (get a i j)) z
+        let foldCol f (z:'T) (a:matrix) j = 
+          rowRange a |> GU.foldR (fun (z:'T) i -> f z (get a i j)) z
+
+        let sum (a:matrix)  = MS.sumM a
+        let prod (a:matrix)  = MS.prodM a
+        let norm  (a:matrix) = MS.normM  a
+        let dot (a:matrix) b = MS.dotM a b
+
+        let cptPow  a y = map (fun x -> x ** y) a
+        
+        // Functions that only make sense on this type
+        let randomize v = map (fun vij -> MRandom.float vij) v      (* res_ij = random [0,vij] values *)
+
+        let ofRowVector x : matrix = MS.rowvecM x
+        let ofVector    x : matrix = MS.vectorM x
+        let toVector    x : vector = MS.toVectorM x
+        let toRowVector x : rowvec = MS.toRowVectorM x
+        let toScalar    x : float  = MS.toScalarM x
+
+        let inplaceAdd  (a:matrix) b = MS.inplaceAddM a b
+        let inplaceSub  (a:matrix) b = MS.inplaceSubM a b
+
+        // Mutation
+        let inplace_assign  f (a:matrix) = MG.inplace_assign f a
+        let inplace_mapi  f (a:matrix) = MG.inplace_mapi f a
+        let inplace_cptMul (a:matrix) b = MS.inplaceCptMulM a b
+        let inplace_scale  a (b:matrix) = MS.inplaceScaleM a b
+
+        let inplace_add  a b = inplaceAdd a b
+        let inplace_sub  a b = inplaceSub a b
+        let of_rowvec x = ofRowVector x
+        let of_vector x = ofVector x
+        let to_vector x = toVector x
+        let to_rowvec x = toRowVector x
+        let to_scalar x = toScalar x
+        let inline of_array2D arr  = ofArray2D arr
+        let inline to_array2D m = toArray2D m
+        let of_list    xss   = ofList xss
+        let of_seq     xss   = ofSeq xss
+        let init_diagonal v   = initDiagonal   v
+        let of_scalar x     = ofScalar x
+        let to_dense x = toDense x
+        let init_dense i j a = initDense i j a
+        let init_sparse i j a = initSparse i j a
+
+
+    end
+
+
+//----------------------------------------------------------------------------
+// module Vector
+//--------------------------------------------------------------------------*)
+      
+    [<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+    module Vector = 
+
+        module Generic = 
+
+            module OpsS = SpecializedGenericImpl
+
+            let get (a:Vector<_>) i   = a.[i]
+            let set (a:Vector<_>) i x = a.[i] <- x
+            let length (v:Vector<_>) = v.Length
+            let ofList    xss   = OpsS.listV xss
+            let ofSeq    xss   = OpsS.seqV xss
+            let init  m   f = OpsS.initV m f
+            let initNumeric  m   f = OpsS.createNumericV m f
+            let ofArray arr       = OpsS.arrayV arr
+            let toArray (v:Vector<_>) = Array.init v.Length (get v)
+
+            let create  m x   = OpsS.constV m x
+            let zero n = OpsS.zeroV n
+            let ones n = OpsS.createNumericV n (fun ops _ -> ops.One)
+            let ofScalar   x = OpsS.scalarV x
+            let add a b = OpsS.addV a b
+            let sub a b = OpsS.subV a b
+            let mulRVV a b = OpsS.mulRVV a b
+            let mulVRV a b = OpsS.mulVRV a b
+            let cptMul a b = OpsS.cptMulV a b
+            let cptMax a b = OpsS.cptMaxV a b
+            let cptMin a b = OpsS.cptMinV a b
+            let scale a b = OpsS.scaleV a b
+            let dot a b = OpsS.dotV a b
+            let neg a = OpsS.negV a 
+            let transpose a = OpsS.transV a 
+            let inplaceAdd a b = OpsS.inplaceAddV a b
+            let inplaceSub a b = OpsS.inplaceSubV a b
+            let inplace_cptMul a b = OpsS.inplaceCptMulV a b
+            let inplace_scale a b = OpsS.inplaceScaleV a b
+
+
+
+            let exists  f a = OpsS.existsV  f a
+            let forall  f a = OpsS.forallV  f a
+            let existsi  f a = OpsS.existsiV  f a
+            let foralli  f a = OpsS.foralliV  f a
+            let map  f a = OpsS.mapV f a
+            let mapi f a = OpsS.mapiV f a
+            let copy a = OpsS.copyV a
+            let inplace_mapi  f a = OpsS.inplace_mapiV f a
+            let fold  f z a = OpsS.foldV f z a
+            let foldi  f z a = OpsS.foldiV f z a
+            let compare a b = OpsS.compareV a b
+            let hash a = OpsS.hashV a
+            let inplace_assign  f a = OpsS.assignV f a
+            let sum  (a:Vector<_>) = let ops = a.ElementOps in fold (fun x y -> ops.Add(x,y)) ops.Zero a
+            let prod (a:Vector<_>) = let ops = a.ElementOps in fold (fun x y -> ops.Multiply(x,y)) ops.One a
+            let norm (a:Vector<_>) = 
+                let normOps = GenericImpl.getNormOps a.ElementOps 
+                sqrt (fold (fun x y -> x + normOps.Norm(y)**2.0) 0.0 a)
+
+            let of_list    xss  = ofList xss
+            let of_seq    xss   = ofSeq xss
+            let of_array arr    = ofArray arr
+            let to_array v      = toArray v
+            let of_scalar   x   = ofScalar x
+            let inplace_add a b = inplaceAdd a b
+            let inplace_sub a b = inplaceSub a b
+
+        module VG = Generic
+        module VecDS = DoubleImpl
+        module VecGU = GenericImpl
+
+        let get (a:vector) j   = VG.get a j 
+        let set (a:vector) j x = VG.set a j x
+        let length (a:vector)     = VG.length a
+        let nrows (a:vector)   = VG.length a
+        let init  m   f = VecDS.createVecDS  m   f
+        let ofArray arr : vector = VG.ofArray arr
+        let toArray (m : vector) = VG.toArray m
+
+        type range = int * int
+        let countR ((a,b) : range)   = (b-a)+1
+        let idxR    ((a,_) : range) i = a+i
+        type rangef = float * float * float // start, skip, end
+        let countRF ((a,d,b) : rangef)   = System.Convert.ToInt32((b-a)/d) + 1
+        //let countRF ((a,d,b) : rangef)   = Float.to_int((b-a)/d) + 1
+        let idxRF  ((a,d,b) : rangef) i = System.Math.Min (a + d * float(i),b)
+
+        let range n1 n2    = let r = (n1,n2)   in init (countR  r) (fun i -> float(idxR r i)) 
+
+        let rangef a b c  = let r = (a,b,c) in init (countRF r) (fun i -> idxRF r i)
+
+        let ofList    xs    = VecDS.listVecDS    xs
+        let ofSeq    xs    = VecDS.seqVecDS    xs
+        let create  m   x  = VecDS.constVecDS  m   x
+        let ofScalar x     = VecDS.scalarVecDS x
+        let add a b = VecDS.addVecDS   a b
+        let sub a b = VecDS.subVecDS   a b
+        let mulRVV a b = VecDS.mulRowVecVecDS   a b
+        let mulVRV a b = VecDS.mulVecRowVecDS   a b 
+        let cptMul a b = VecDS.cptMulVecDS   a b
+        let cptMax a b = VecDS.cptMaxVecDS a b
+        let cptMin a b = VecDS.cptMinVecDS a b
+        let scale a b = VecDS.scaleVecDS   a b
+        let neg a  = VecDS.negVecDS a
+        let dot a b = VecDS.dotVecDS a b
+        let transpose  (a:vector) = VG.transpose a
+        let exists  f (a:vector) = VG.exists f a
+        let forall  f (a:vector) = VG.forall f a
+        let existsi  f (a:vector) = VG.existsi f a
+        let foralli  f (a:vector) = VG.foralli f a
+        let map  f (a:vector) = VG.map f a
+        let copy (a:vector) = VG.copy a
+        let mapi  f (a:vector) : vector = VG.mapi f a
+        let fold  f z (a:vector) = VG.fold f z a
+        let foldi  f z (a:vector) = VG.foldi f z a
+        let zero n = create n 0.0
+        let ones n = create n 1.0
+        let sum a  = VecDS.sumVecDS a
+        let prod a   = fold      (fun x y -> x * y) 1.0 a
+        let norm  (a:vector) = sqrt (fold (fun x y -> x + y * y) 0.0 a) (* fixed *)
+        let cptPow  a y = map  (fun x -> x ** y) a
+        let inplace_assign  f (a:vector) = VG.inplace_assign f a
+        let inplace_mapi f (a:vector) = VG.inplace_mapi f a
+        let inplace_add a b = VecDS.inplaceAddVecDS a b
+        let inplace_sub a b = VecDS.inplaceSubVecDS a b
+        let inplace_cptMul a b = VecDS.inplaceCptMulVecDS a b
+        let inplace_scale a b = VecDS.inplaceScaleVecDS a b  
+
+        let of_array arr   = ofArray arr
+        let to_array m     = toArray m
+        let of_list    xs  = ofList xs
+        let of_seq    xs   = ofSeq xs
+        let of_scalar x    = ofScalar x
+
+
+
+//----------------------------------------------------------------------------
+// module RowVector
+//--------------------------------------------------------------------------*)
+
+    [<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+    module RowVector = 
+
+        module Generic = 
+
+            module OpsS = SpecializedGenericImpl
+
+            let get (a:RowVector<_>) i          = a.[i]
+            let set (a:RowVector<_>) i x        = a.[i] <- x
+            let zero n           = OpsS.zeroRV n
+            let length (v:RowVector<_>) = v.Length
+            let init m   f       = OpsS.initRV m   f
+            let create  m x      = OpsS.constRV m x
+            let transpose a      = OpsS.transRV a
+            let copy a           = OpsS.copyRV a
+            let ofList a         = OpsS.listRV a
+            let ofArray a        = OpsS.arrayRV a
+            let ofSeq a          = OpsS.seqRV a
+            let toArray m        = Array.init (length m) (get m)
+
+            let of_list a        = ofList a
+            let of_array a       = ofArray a
+            let of_seq a         = ofSeq a
+            let to_array m       = toArray m
+
+
+        module RVG = Generic
+
+        let get (a:rowvec) i   = RVG.get a i 
+        let set (a:rowvec) i x = RVG.set a i x
+        let length (a:rowvec)  = RVG.length a
+        let ncols (a:rowvec)   = RVG.length a
+        let ofArray arr : rowvec = RVG.ofArray arr
+        let toArray (m : rowvec) = RVG.toArray m
+        
+        let init m   f : rowvec      = RVG.init m   f
+        let create m   f : rowvec    = RVG.create m   f
+        let zero n = create n 0.0
+        let ofList x : rowvec       = RVG.ofList x
+        let ofSeq x : rowvec       = RVG.ofSeq x
+        let transpose x : vector     = RVG.transpose x
+        let copy x : rowvec          = RVG.copy x
+
+        let of_list x    = ofList x
+        let of_seq x     = ofSeq x
+        let of_array arr = ofArray arr
+        let to_array m   = toArray m
+
+
+    type Matrix<'T> with 
+        member x.ToArray2()        = Matrix.Generic.toArray2D x
+        member x.ToArray2D()        = Matrix.Generic.toArray2D x
+
+#if FX_NO_DEBUG_DISPLAYS
+#else
+        [<DebuggerBrowsable(DebuggerBrowsableState.Collapsed)>]
+#endif
+
+        member x.NonZeroEntries    = Matrix.Generic.nonzero_entries x
+        member x.ToScalar()        = Matrix.Generic.toScalar x
+        member x.ToRowVector()     = Matrix.Generic.toRowVector x               
+        member x.ToVector()        = Matrix.Generic.toVector x
+
+#if FX_NO_DEBUG_DISPLAYS
+#else
+        [<DebuggerBrowsable(DebuggerBrowsableState.Collapsed)>]
+#endif
+        member x.Norm              = Matrix.Generic.norm x
+
+        member x.Column(n)         = Matrix.Generic.getCol x n
+        member x.Row(n)            = Matrix.Generic.getRow x n
+        member x.Columns (i,ni)    = Matrix.Generic.getCols x i ni
+        member x.Rows (j,nj)       = Matrix.Generic.getRows x j nj
+        member x.Region(i,j,ni,nj) = Matrix.Generic.getRegion x i j ni nj
+        member x.GetDiagonal(i)    = Matrix.Generic.getDiagN x i
+
+#if FX_NO_DEBUG_DISPLAYS
+#else
+        [<DebuggerBrowsable(DebuggerBrowsableState.Collapsed)>]
+#endif
+        member x.Diagonal          = Matrix.Generic.getDiag x
+
+        member x.Copy () = Matrix.Generic.copy x
+
+
+    type Vector<'T> with 
+        member x.ToArray() = Vector.Generic.toArray x
+        member x.Norm      = Vector.Generic.norm x
+        member x.Copy ()   = Vector.Generic.copy x
+
+
+    type RowVector<'T> with 
+        member x.ToArray() = RowVector.Generic.toArray x
+        member x.Copy ()   = RowVector.Generic.copy x
+
+
+    module MatrixTopLevelOperators = 
+
+        let matrix ll = Matrix.ofSeq ll
+        let vector l  = Vector.ofSeq  l
+        let rowvec l  = RowVector.ofSeq l
+
--- fsharp-3.1.1.26+dfsg2.orig/FSharp.PowerPack/math/matrix.fsi
+++ fsharp-3.1.1.26+dfsg2/FSharp.PowerPack/math/matrix.fsi
@@ -1,1100 +1,1100 @@
-// (c) Microsoft Corporation 2005-2009. 
-
-namespace Microsoft.FSharp.Math
-
-open Microsoft.FSharp.Math
-open System
-open System.Collections
-open System.Collections.Generic
-
-/// The type of matrices. The arithmetic operations on the element type are determined by inspection on the element type itself.
-/// Two representations are supported: sparse and dense. 
-[<Sealed>]
-type Matrix<'T> = 
-
-    /// Get the number of rows in a matrix
-    member NumRows : int
-
-    /// Get the number of columns in a matrix
-    member NumCols : int
-
-    /// Get the number of (rows,columns) in a matrix
-    member Dimensions : int * int
-
-    /// Get the item at the given position in a matrix
-    member Item : int * int -> 'T with get,set
-
-    /// Supports the slicing syntax 'A.[idx1..idx2,idx1..idx2]'
-    member GetSlice : start1:int option * finish1:int option * start2:int option * finish2:int option -> Matrix<'T>
-
-    /// Supports the slicing syntax 'A.[idx1..idx2,idx1..idx2] <- B'
-    member SetSlice : start1:int option * finish1:int option * start2:int option * finish2:int option * source:Matrix<'T> -> unit
-    
-    /// Retrieve the dictionary of numeric operations associated with the element
-    /// type of this matrix. Accessing the property may raise an NotSupportedException if the element
-    /// type doesn't support any numeric operations. The object returned
-    /// may support additional numeric operations such as IFractional: 
-    /// this can be determined by a dynamic type test against the object
-    /// returned.
-    member ElementOps : INumeric<'T>
-
-    /// Point-wise addition of two matrices. An InvalidArgument exception will be
-    /// raised if the dimensions do not match.
-    static member ( +  ) : Matrix<'T> * Matrix<'T> -> Matrix<'T>
-
-    /// Point-wise subtraction of two matrices. An InvalidArgument exception will be
-    /// raised if the dimensions do not match.
-    static member ( -  ) : Matrix<'T> * Matrix<'T> -> Matrix<'T>
-
-    /// Matrix negation. 
-    static member ( ~- ) : Matrix<'T>              -> Matrix<'T>
-
-    /// Prefix '+' operator. A nop.
-    static member ( ~+ ) : Matrix<'T>              -> Matrix<'T>
-
-    /// Matrix multiplication. An InvalidArgument exception will be
-    /// raised if the dimensions do not match.
-    static member ( * ) : Matrix<'T> * Matrix<'T> -> Matrix<'T>
-
-    /// Matrix-vector multiplication. 
-    static member ( * ) : Matrix<'T> * Vector<'T> -> Vector<'T>
-
-    /// Multiply each element of a matrix by the given scalar value
-    static member ( * ) : Matrix<'T> * 'T          -> Matrix<'T>
-
-    /// Point-wise matrix multiplication. An InvalidArgument exception will be
-    /// raised if the dimensions do not match.
-    static member ( .* ) : Matrix<'T> * Matrix<'T>  -> Matrix<'T>
-
-    /// Multiply each element of a matrix by a scalar value
-    static member ( * ) : 'T          * Matrix<'T> -> Matrix<'T>
-    
-    /// Get the transpose of a matrix.
-    member Transpose : Matrix<'T>
-    
-    /// Permutes the rows of a matrix.
-    member PermuteRows : permutation:(int -> int) -> Matrix<'T>
-    
-    /// Permutes the columns of a matrix.
-    member PermuteColumns : permutation:(int -> int) -> Matrix<'T>
-
-
-    //interface IMatrix<'T>
-    interface IComparable
-    interface IStructuralComparable
-    interface IStructuralEquatable
-    interface IEnumerable<'T>
-    override GetHashCode : unit -> int
-    override Equals : obj -> bool
-  
-    /// Return a new array containing the elements of a matrix
-    member ToArray2D : unit -> 'T[,]  
-
-    /// Return the non-zero entries of a sparse or dense matrix
-    member NonZeroEntries: seq<int * int * 'T> 
-
-    /// Convert a matrix to a row vector
-    member ToRowVector : unit -> RowVector<'T>                 
-
-    /// Convert a matrix to a column vector
-    member ToVector : unit -> Vector<'T> 
-
-    /// Returns sqrt(sum(norm(x)*(norm(x))) of all the elements of a matrix.
-    /// The element type of a matrix must have an associated instance of INormFloat<'T> (see <c>GlobalAssociations</c>) ((else NotSupportedException)).
-    member Norm : float
-
-    /// Select a column from a matrix
-    member Column : index:int -> Vector<'T>
-
-    /// Select a row from a matrix
-    member Row :  index:int -> RowVector<'T>
-
-    /// Select a range of columns from a matrix
-    member Columns : start:int  * length:int -> Matrix<'T>
-
-    /// Select a range of rows from a matrix
-    member Rows : start:int * length:int -> Matrix<'T>
-
-    /// Select a region from a matrix
-    member Region : starti:int * startj:int * lengthi:int * lengthj:int -> Matrix<'T>
-
-
-    /// Return the nth diagonal of a matrix, as a vector. Diagonal 0 is the primary
-    /// diagonal, positive diagonals are further to the upper-right of a matrix.
-    member GetDiagonal : int -> Vector<'T>
-
-    /// Get the main diagonal of a matrix, as a vector
-    member Diagonal : Vector<'T>
-
-    /// Create a new matrix that is a copy of an array
-    member Copy : unit -> Matrix<'T>
-
-    /// Get the internal array of values for a dense matrix. This property 
-    /// should only be used when interoperating with other matrix libraries.
-    member InternalDenseValues : 'T[,]
-    /// Get the internal array of values for a sparse matrix. This property 
-    /// should only be used when interoperating with other matrix libraries.
-    member InternalSparseValues : 'T[]
-    /// Get the internal array of row offsets for a sparse matrix. This property 
-    /// should only be used when interoperating with other matrix libraries.
-    member InternalSparseRowOffsets : int[]
-    /// Get the internal array of column values for a sparse matrix. This property 
-    /// should only be used when interoperating with other matrix libraries.
-    member InternalSparseColumnValues : int[]
-
-    /// Indicates if a matrix uses the sparse representation.
-    member IsSparse : bool
-
-    /// Indicates if a matrix uses the dense representation.
-    member IsDense : bool
-
-    [<System.Obsolete("This member has been renamed to 'ToArray2D'")>]
-    member ToArray2 : unit -> 'T[,]  
-
-    member StructuredDisplayAsArray : obj
-
-/// The type of column vectors. The arithmetic operations on the element type are determined by inspection 
-/// on the element type itself
-and 
-
-  [<Sealed>]
-  Vector<'T> = 
-
-
-    /// Get the underlying internal array of values for a vector. This property 
-    /// should only be used when interoperating with other matrix libraries.
-    member InternalValues : 'T[]
-
-    /// Gets the number of entries in a vector
-    member Length : int
-
-    /// Gets the number of rows in a vector
-    member NumRows : int
-
-    /// Gets an item from a vector
-    member Item : int -> 'T with get,set
-
-    /// Gets the element operations for the element type of a vector, if any
-    member ElementOps : INumeric<'T>
-    
-    /// Supports the slicing syntax 'v.[idx1..idx2]'
-    member GetSlice      : start:int option * finish:int option -> Vector<'T>
-
-    /// Supports the slicing syntax 'v.[idx1..idx2] <- v2'
-    member SetSlice      : start:int option * finish:int option * source:Vector<'T> -> unit
-
-    /// Add two vectors, pointwise
-    static member ( +  ) : Vector<'T>    * Vector<'T> -> Vector<'T>
-
-    /// Subtract two vectors, pointwise
-    static member ( -  ) : Vector<'T>    * Vector<'T> -> Vector<'T>
-
-    /// Negate a vector
-    static member ( ~- ) : Vector<'T>                  -> Vector<'T>
-
-    /// Return the input vector 
-    static member ( ~+ ) : Vector<'T>                  -> Vector<'T>
-
-    /// Point-wise multiplication of two vectors.
-    static member ( .* ) : Vector<'T>    * Vector<'T> -> Vector<'T>
-
-    /// Multiply each element of a vector by a scalar value.
-    static member ( * ) : 'T             * Vector<'T> -> Vector<'T>
-
-    /// Multiply a column vector and a row vector to produce a matrix
-    static member ( * )   : Vector<'T>    * RowVector<'T> -> Matrix<'T>
-
-    /// Multiply a vector by a scalar
-    static member ( * )   : Vector<'T>    * 'T          -> Vector<'T>
-
-    /// Get the transpose of a vector.
-    member Transpose : RowVector<'T>
-    
-    /// Permute the elements of a vector.
-    member Permute : permutation:(int -> int) -> Vector<'T>    
-    
-    interface IComparable
-    interface IStructuralComparable
-    interface IStructuralEquatable
-    interface IEnumerable<'T>
-    override GetHashCode : unit -> int
-    override Equals : obj -> bool
-
-    /// Return a new array containing a copy of the elements of a vector
-    member ToArray : unit    -> 'T[]
-
-    /// Computes the 2-norm of a vector: sqrt(x.Transpose*x).
-    member Norm : float
-
-    /// Create a new matrix that is a copy of a array
-    member Copy : unit -> Vector<'T>
-
-    member StructuredDisplayAsArray : 'T[]
-
-
-
-
-/// The type of row vectors. 
-and [<Sealed>]
-    RowVector<'T> =
-
-    /// Get the underlying internal array of values for a vector. This property 
-    /// should only be used when interoperating with other matrix libraries.
-    member InternalValues : 'T[]
-
-    // Basic access
-    member Length : int
-    member NumCols : int
-    member Item : int -> 'T with get,set
-    member ElementOps : INumeric<'T>
-
-    /// Supports the slicing syntax 'rv.[idx1..idx2]'
-    member GetSlice      : start:int option * finish:int option -> RowVector<'T>
-
-    /// Supports the slicing syntax 'rv.[idx1..idx2] <- rv2'
-    member SetSlice      : start:int option * finish:int option * source:RowVector<'T> -> unit
-
-
-    /// Point-wise addition of two row vectors
-    static member ( +  )  : RowVector<'T>    * RowVector<'T> -> RowVector<'T>
-
-    /// Point-wise subtraction of two row vectors
-    static member ( -  )  : RowVector<'T>    * RowVector<'T> -> RowVector<'T>
-
-    /// Point-wise negation of a row vector
-    static member ( ~- )  : RowVector<'T>                  -> RowVector<'T>
-
-    /// Return a row vector, unchanged
-    static member ( ~+ )  : RowVector<'T>                  -> RowVector<'T>
-
-    /// Point-wise multiplication of two row vectors
-    static member ( .* )  : RowVector<'T> * RowVector<'T>    -> RowVector<'T>
-    
-    /// Multiply a row vector by a vector
-    static member ( * ) : RowVector<'T> * Vector<'T>    -> 'T
-
-    /// Multiply a row vector by a matrix
-    static member ( * )   : RowVector<'T> * Matrix<'T>    -> RowVector<'T>
-
-    /// Multiply a row vector by a scalar
-    static member ( * )   : RowVector<'T> * 'T            -> RowVector<'T>
-
-    /// Multiply a scalar by a row vector
-    static member ( * )  : 'T            * RowVector<'T>    -> RowVector<'T>
-
-    /// Get the transpose of the row vector.
-    member Transpose : Vector<'T>
-    
-    /// Permute the elements of the row vector.
-    member Permute : permutation:(int -> int) -> RowVector<'T>  
-
-    interface IComparable
-    interface IStructuralComparable
-    interface IStructuralEquatable
-    interface IEnumerable<'T>
-    override GetHashCode : unit -> int
-    override Equals : obj -> bool
-
-    /// Return a new array containing a copy of the elements of a vector
-    member ToArray : unit    -> 'T[]
-
-    /// Create a new matrix that is a copy of a array
-    member Copy : unit -> RowVector<'T>
-
-    member StructuredDisplayAsArray : 'T[]
-  
-/// The type of floating point matrices
-type matrix = Matrix<float>
-/// The type of floating point column vectors
-type vector = Vector<float>
-/// The type of floating point row vectors
-type rowvec = RowVector<float>
-
-/// Operations to manipulate floating
-/// point matrices. The submodule <c>Matrix.Generic</c> contains a 
-/// matching set of operations to manipulate matrix types carrying
-/// arbitrary element types.
-[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
-[<RequireQualifiedAccess>]
-module Matrix =
-
-
-    /// Get an element of a matrix
-    val get : matrix -> int -> int -> float
-
-    /// Set an element of a matrix
-    val set : matrix -> int -> int -> float -> unit
-
-    // Creation: general
-    val init  : int -> int -> (int -> int -> float) -> matrix
-
-    /// Create a matrix with all entries the given constant
-    val create : int -> int -> float -> matrix
-    
-    /// Create a dense representation matrix with the given entries. 
-    val initDense : int -> int -> seq<int * int * float> -> matrix
-
-    /// Create a sparse representation matrix with the given entries. Not all 
-    /// operations are available for sparse matrices, and mutation is not permitted.
-    /// If an operation on sparse matrices raises a runtime exception then consider 
-    /// converting to a dense matrix using to_dense.
-    val initSparse : int -> int -> seq<int * int * float> -> matrix
-
-    /// Create a matrix with all entries zero
-    val zero     : int -> int          -> matrix
-    
-    /// Create a square matrix with the constant 1.0 lying on diagonal
-    val identity      : int -> matrix
-
-    /// Create a square matrix with a vector lying on diagonal
-    val initDiagonal : vector -> matrix
-    
-    /// Create a matrix from the given data
-    val ofList   : float list list     -> matrix
-
-    /// Create a matrix from the given data
-    val ofSeq    : seq<#seq<float>>   -> matrix
-
-    /// Create a matrix from the given data
-    val ofArray2D : float[,]            -> matrix
-
-    /// Return a new array containing the elements of the given matrix
-    val toArray2D : matrix              -> float[,]
-
-
-    /// Create a 1x1 matrix containing the given value 
-    val ofScalar : float               -> matrix
-    /// Create a matrix with one row from the given row vector
-    val ofRowVector : rowvec              -> matrix
-    /// Create a matrix with one column from the given vector
-    val ofVector : vector              -> matrix
-
-    /// Return the element at row 0, column 0 of a matrix
-    val toScalar : matrix              -> float                
-    /// Return the first row of a matrix
-    val toRowVector : matrix              -> rowvec                
-    /// Return the first column of a matrix
-    val toVector : matrix              -> vector
-    /// Ensure that a matrix uses dense representation
-    val toDense  : matrix              -> matrix
-
-    /// Point-wise maximum element of two matrices
-    val cptMax    : matrix -> matrix -> matrix
-    
-    /// Point-wise minimum element of two matrices
-    val cptMin    : matrix -> matrix -> matrix
-    
-    /// Add two matrices (operator +)
-    val add       : matrix -> matrix -> matrix
-
-    /// Dot product
-    val dot       : matrix -> matrix -> float
-
-    /// Point-wise exponential of a matrix.
-    val cptPow       : matrix -> float -> matrix
-
-    /// Transpose of a matrix. Use also m.Transpose
-    val transpose     :           matrix -> matrix
-
-    /// Sum of the diagonal elements of a matrix
-    val trace     : matrix -> float
-    
-    /// Generate a new matrix of the same size as the input with random entries 
-    /// drawn from the range 0..aij. Random numbers are generated using a globally 
-    /// shared System.Random instance with the initial seed 99.
-    val randomize : matrix -> matrix
-
-    /// Sum all the elements of a matrix
-    val sum       : matrix -> float
-
-    ///Multiply all the elements of a matrix
-    val prod      : matrix -> float
-
-    ///sqrt(sum(x*x)) of all the elements of a matrix
-    val norm      : matrix -> float
-
-    /// Check if a predicate holds for all elements of a matrix
-    val forall  : (float -> bool) -> matrix -> bool
-
-    /// Check if a predicate holds for at least one element of a matrix
-    val exists  : (float -> bool) -> matrix -> bool 
-
-    /// Check if a predicate holds for all elements of a matrix
-    val foralli  : (int -> int -> float -> bool) -> matrix -> bool
-
-    /// Check if a predicate holds for at least one element of a matrix
-    val existsi  : (int -> int -> float -> bool) -> matrix -> bool 
-
-    /// Fold a function over all elements of a matrix
-    val fold      : ('T -> float -> 'T) -> 'T         -> matrix -> 'T
-
-    /// Fold an indexed function over all elements of a matrix
-    val foldi      : (int -> int -> 'T -> float -> 'T) -> 'T         -> matrix -> 'T
-
-    /// Fold a function down each column of a matrix
-    val foldByCol : ('T -> float -> 'T) -> RowVector<'T> -> matrix -> RowVector<'T>
-
-    /// Fold a function along each row of a matrix
-    val foldByRow : ('T -> float -> 'T) -> Vector<'T> -> matrix -> Vector<'T>
-
-    /// Fold a function along a particular column of a matrix
-    val foldCol   : ('T -> float -> 'T) -> 'T         -> matrix -> int -> 'T 
-
-    /// Fold a function down a particular row of a matrix
-    val foldRow   : ('T -> float -> 'T) -> 'T         -> matrix -> int -> 'T
-    
-    /// Map a function over each element of a matrix, producing a new matrix
-    val map  : (float -> float) -> matrix -> matrix
-   
-    /// Map the given indexed function over each element of a matrix, producing a new matrix
-    val mapi  : (int -> int -> float -> float) -> matrix -> matrix
-   
-    /// Create a new matrix that is a copy of the given array
-    val copy : matrix -> matrix
-   
-    /// In-place addition, mutating the first matrix argument.
-    val inplaceAdd    : matrix -> matrix -> unit
-
-    /// In-place subtraction, mutating the first matrix argument. 
-    val inplaceSub    : matrix -> matrix -> unit
-
-    [<Obsolete("Use the '.NonZeroEntries' property instead")>]
-    val nonzero_entries : matrix -> seq<int * int * float>         
-    [<System.Obsolete("This function has been renamed. Use 'Matrix.inplaceAdd' instead")>]
-    val inplace_add    : matrix -> matrix -> unit
-    [<System.Obsolete("This function has been renamed. Use 'Matrix.inplaceSub' instead")>]
-    val inplace_sub    : matrix -> matrix -> unit
-    [<System.Obsolete("This function has been renamed. Use 'Matrix.ofList' instead")>]
-    val of_list   : float list list     -> matrix
-    [<System.Obsolete("This function has been renamed. Use 'Matrix.ofSeq' instead")>]
-    val of_seq    : seq<#seq<float>>   -> matrix
-    [<System.Obsolete("This function has been renamed. Use 'Matrix.ofArray2D' instead")>]
-    val inline of_array2D : float[,]            -> matrix
-    [<System.Obsolete("This function has been renamed. Use 'Matrix.toArray2D' instead")>]
-    val inline to_array2D : matrix              -> float[,]
-    [<System.Obsolete("This function has been renamed. Use 'Matrix.ofScalar' instead")>]
-    val of_scalar : float               -> matrix
-    [<System.Obsolete("This function has been renamed. Use 'Matrix.ofRowVector' instead")>]
-    val of_rowvec : rowvec              -> matrix
-    [<System.Obsolete("This function has been renamed. Use 'Matrix.ofVector' instead")>]
-    val of_vector : vector              -> matrix
-    [<System.Obsolete("This function has been renamed. Use 'Matrix.toScalar' instead")>]
-    val to_scalar : matrix              -> float                
-    [<System.Obsolete("This function has been renamed. Use 'Matrix.toRowVector' instead")>]
-    val to_rowvec : matrix              -> rowvec                
-    [<System.Obsolete("This function has been renamed. Use 'Matrix.toVector' instead")>]
-    val to_vector : matrix              -> vector
-    [<System.Obsolete("This function has been renamed. Use 'Matrix.toDense' instead")>]
-    val to_dense  : matrix              -> matrix
-    [<Obsolete("Use the '*' operator instead")>]
-    val mul       : matrix -> matrix -> matrix
-    [<Obsolete("This function has been renamed to 'initDiagonal'")>]
-    val init_diagonal : vector -> matrix
-    [<Obsolete("Use the 'Matrix.init' function instead")>]
-    val constDiag : int -> float        -> matrix
-    [<Obsolete("Use the 'initDiagonal' function instead")>]
-    val diag      : vector -> matrix
-    [<Obsolete("This function has been renamed to 'initDense'")>]
-    val init_dense : int -> int -> seq<int * int * float> -> matrix
-    [<Obsolete("This function has been renamed to 'initSparse'")>]
-    val init_sparse : int -> int -> seq<int * int * float> -> matrix
-    [<Obsolete("Use the '.*' operator instead")>]
-    val cptMul    : matrix -> matrix -> matrix
-    [<Obsolete("Use the '*' operator instead")>]
-    val mulV      : matrix -> vector -> vector
-    [<Obsolete("Use the '*' operator instead")>]
-    val mulRV     : rowvec -> matrix -> rowvec
-    [<Obsolete("Use the '-' operator instead")>]
-    val sub       : matrix -> matrix -> matrix
-    [<Obsolete("Use the '-' prefix operator instead")>]
-    val neg       :           matrix -> matrix
-    [<Obsolete("Use the '*' operator instead")>]
-    val scale     : float  -> matrix -> matrix
-    [<Obsolete("Use the '.Column' method instead")>]
-    val getCol  : matrix -> int -> vector
-    [<Obsolete("Use the '.Row' method instead")>]
-    val getRow  : matrix -> int -> rowvec
-    [<Obsolete("Use the '.Columns' method instead")>]
-    val getCols : matrix -> start:int -> length:int -> matrix
-    [<Obsolete("Use the '.Rows' method instead")>]
-    val getRows : matrix -> start:int -> length:int -> matrix
-    [<Obsolete("Use the '.Region' method instead")>]
-    val getRegion  : matrix -> starti:int -> startj:int -> lengthi:int -> lengthj:int -> matrix
-    [<Obsolete("Use the '.Diagonal' method instead")>]
-    val getDiagN : matrix -> int    -> vector
-    [<Obsolete("Use the '.Diagonal' property instead")>]
-    val getDiag  : matrix           -> vector
-    [<Obsolete("This function will be removed in a future revision of this library. Set the elements of the matrix directly instead using 'm.[i,j] <- v'")>]
-    val inplace_assign       : (int -> int -> float) -> matrix -> unit
-    [<Obsolete("This function will be removed in a future revision of this library. Set the elements of the matrix directly instead using 'm.[i,j] <- v'")>]
-    val inplace_mapi  : (int -> int -> float -> float) -> matrix -> unit
-    [<Obsolete("This function will be removed in a future revision of this library. Set the elements of the matrix directly instead using 'm.[i,j] <- v'")>]
-    val inplace_cptMul : matrix -> matrix -> unit
-    [<Obsolete("This function will be removed in a future revision of this library. Set the elements of the matrix directly instead using 'm.[i,j] <- v'")>]
-    val inplace_scale  : float -> matrix -> unit
-
-    /// Operations to manipulate matrix types carrying
-    /// arbitrary element types. The names and types of the operations match those
-    /// in the containing module Math.Matrix. 
-    ///
-    /// The numeric operations on the element type (add, zero etc.) are inferred from the type
-    /// argument itself. That is, for some operations 
-    /// the element type of a matrix must have an associated instance of INumeric<'T> 
-    /// or some more specific numeric association (see <c>GlobalAssociations</c>) ((else NotSupportedException)).
-    [<RequireQualifiedAccess>]
-    module Generic =
-
-        /// Get an element from a matrix. The indexes are given in row/column order.
-        val get   : Matrix<'T> -> int -> int -> 'T
-        /// Set an element in a matrix. The indexes are given in row/column order.
-        val set   : Matrix<'T> -> int -> int -> 'T -> unit
-
-        /// Create a matrix from the given data  
-        val ofList      : 'T list list       -> Matrix<'T>
-
-        /// Create a matrix from the given data  
-        val ofSeq       : seq<#seq<'T>>     -> Matrix<'T>
-
-        /// Create a matrix from the given data  
-        val ofArray2D    : 'T[,]              -> Matrix<'T>
-
-        /// Return a new array containing the elements of the given matrix
-        val toArray2D : Matrix<'T>         -> 'T[,]  
-
-        /// Create a matrix containing the given value at every element.
-        val create     : int -> int -> 'T   -> Matrix<'T>
-
-        /// Create a dense matrix from the given sequence of elements
-        val initDense : int -> int -> seq<int * int * 'T>  -> Matrix<'T>
-
-        /// Create a sparse matrix from the given sequence of elements
-        val initSparse : int -> int -> seq<int * int * 'T>  -> Matrix<'T>
-
-        /// Create a 1x1 matrix containing the given value 
-        val ofScalar    : 'T                 -> Matrix<'T>
-
-        /// Create a matrix from a row vector
-        val ofRowVector  : RowVector<'T>     -> Matrix<'T>
-        /// Create a matrix from a column vector
-        val ofVector  : Vector<'T>        -> Matrix<'T>
-
-        /// Get the element at column zero, row zero
-        val toScalar : Matrix<'T>         -> 'T                
-        /// Extract the first row of a matrix
-        val toRowVector : Matrix<'T>         -> RowVector<'T>                 
-        /// Extract the first column of a matrix
-        val toVector : Matrix<'T>         -> Vector<'T> 
-
-
-        /// Create a matrix using a function to compute the item at each index.
-        val init : int -> int -> (int -> int -> 'T) -> Matrix<'T>
-
-        /// Create a matrix using a function to compute the item at each index.
-        /// The element type of a matrix must have an associated instance of INumeric<'T> (see <c>GlobalAssociations</c>) ((else NotSupportedException)).
-        /// The function is passed the dictionary of associated operations in addition to the index pair.
-        val initNumeric  : int -> int -> (INumeric<'T> -> int -> int -> 'T)        -> Matrix<'T>
-
-        /// Create a matrix containing the zero element at each index.
-        /// The element type of a matrix must have an associated instance of INumeric<'T> (see <c>GlobalAssociations</c>) ((else NotSupportedException)).
-        val zero      : int -> int         -> Matrix<'T>
-
-        /// Create a square matrix with the one for the element type lying on diagonal
-        /// The element type of a matrix must have an associated instance of INumeric<'T> (see <c>GlobalAssociations</c>) ((else NotSupportedException)).
-        val identity      : int -> Matrix<'T>
-
-        /// Create a matrix containing the given vector along the diagonal.
-        /// The element type of a matrix must have an associated instance of INumeric<'T> (see <c>GlobalAssociations</c>) ((else NotSupportedException)).
-        val initDiagonal : Vector<'T>        -> Matrix<'T>
-
-        ///Take the pointwise maximum of two matrices
-        val cptMax    : Matrix<'T> -> Matrix<'T> -> Matrix<'T> when 'T : comparison
-
-        ///Take the pointwise maximum of two matrices
-        val cptMin    : Matrix<'T> -> Matrix<'T> -> Matrix<'T> when 'T : comparison
-
-        /// Sum of the point-wise multiple of the two matrices.
-        /// The element type of a matrix must have an associated instance of INumeric<'T> (see <c>GlobalAssociations</c>) ((else NotSupportedException)).
-        val dot       : Matrix<'T> -> Matrix<'T> -> 'T
-
-
-        /// Return a new matrix which is the transpose of the input matrix
-        val transpose : Matrix<'T> -> Matrix<'T>
-
-        /// Compute the sum of the diagonal of a square matrix
-        val trace     : Matrix<'T> -> 'T
-        /// Compute the sum of the elements in a matrix
-        val sum       : Matrix<'T> -> 'T
-        /// Compute the product of the elements in a matrix
-        val prod      : Matrix<'T> -> 'T
-        /// Returns sqrt(sum(norm(x)*(norm(x))) of all the elements of a matrix.
-        /// The element type of a matrix must have an associated instance of INormFloat<'T> (see <c>GlobalAssociations</c>) ((else NotSupportedException)).
-        val norm      : Matrix<'T> -> float
-
-        /// Fold a function over all elements of a matrix
-        val fold  : folder:('State -> 'T -> 'State) -> 'State -> Matrix<'T> -> 'State
-
-        /// Fold an indexed function over all elements of a matrix
-        val foldi  : (int -> int -> 'State -> 'T -> 'State) -> 'State -> Matrix<'T> -> 'State
-
-        /// Return true if a predicate returns true for all values in a matrix
-        val forall: ('T -> bool)           -> Matrix<'T> -> bool
-
-        /// Return true if a predicate returns true for some value in a matrix
-        val exists: ('T -> bool)           -> Matrix<'T> -> bool 
-
-        /// Return true if an indexed predicate returns true for all values in a matrix
-        val foralli: (int -> int -> 'T -> bool)           -> Matrix<'T> -> bool
-
-        /// Return true if an indexed predicate returns true for some value in a matrix
-        val existsi: (int -> int -> 'T -> bool)           -> Matrix<'T> -> bool 
-
-        /// Create a new matrix that is a copy of the given array
-        val copy : Matrix<'T> -> Matrix<'T>
-   
-        /// Map a function over a matrix
-        val map   : ('T -> 'T) -> Matrix<'T> -> Matrix<'T>
-
-        /// Map the given position-indexed function over a matrix
-        val mapi  : (int -> int -> 'T -> 'T) -> Matrix<'T> -> Matrix<'T>
-
-        /// Add the second matrix to the first by, mutating the first
-        val inplaceAdd    : Matrix<'T> -> Matrix<'T> -> unit
-        /// Subtract the second matrix from the first, by mutating the first
-        val inplaceSub    : Matrix<'T> -> Matrix<'T> -> unit
-
-        [<System.Obsolete("This function has been renamed. Use 'Matrix.Generic.inplaceAdd' instead")>]
-        val inplace_add    : Matrix<'T> -> Matrix<'T> -> unit
-        [<System.Obsolete("This function has been renamed. Use 'Matrix.Generic.inplaceSub' instead")>]
-        val inplace_sub    : Matrix<'T> -> Matrix<'T> -> unit
-        [<System.Obsolete("This function has been renamed. Use 'Matrix.Generic.ofList' instead")>]
-        val of_list      : 'T list list       -> Matrix<'T>
-        [<System.Obsolete("This function has been renamed. Use 'Matrix.Generic.ofSeq' instead")>]
-        val of_seq       : seq<#seq<'T>>     -> Matrix<'T>
-        [<System.Obsolete("This function has been renamed. Use 'Matrix.Generic.ofArray2D' instead")>]
-        val inline of_array2D    : 'T[,]              -> Matrix<'T>
-        [<System.Obsolete("This function has been renamed. Use 'Matrix.Generic.toArray2D' instead")>]
-        val inline to_array2D : Matrix<'T>         -> 'T[,]  
-        [<System.Obsolete("This function has been renamed. Use 'Matrix.Generic.ofScalar' instead")>]
-        val of_scalar    : 'T                 -> Matrix<'T>
-        [<System.Obsolete("This function has been renamed. Use 'Matrix.Generic.ofRowVector' instead")>]
-        val of_rowvec  : RowVector<'T>     -> Matrix<'T>
-        [<System.Obsolete("This function has been renamed. Use 'Matrix.Generic.ofVector' instead")>]
-        val of_vector  : Vector<'T>        -> Matrix<'T>
-        [<System.Obsolete("This function has been renamed. Use 'Matrix.Generic.toScalar' instead")>]
-        val to_scalar : Matrix<'T>         -> 'T                
-        [<System.Obsolete("This function has been renamed. Use 'Matrix.Generic.toRowVector' instead")>]
-        val to_rowvec : Matrix<'T>         -> RowVector<'T>                 
-        [<System.Obsolete("This function has been renamed. Use 'Matrix.Generic.toVector' instead")>]
-        val to_vector : Matrix<'T>         -> Vector<'T> 
-        [<Obsolete("This function has been renamed to 'initDiagonal'")>]
-        val init_diagonal : Vector<'T>        -> Matrix<'T>
-        [<Obsolete("This function has been renamed to 'initDense'")>]
-        val init_dense : int -> int -> seq<int * int * 'T>  -> Matrix<'T>
-        [<Obsolete("This function has been renamed to 'initSparse'")>]
-        val init_sparse : int -> int -> seq<int * int * 'T>  -> Matrix<'T>
-        [<Obsolete("Use the '.NonZeroEntries' property instead")>]
-        val nonzero_entries : Matrix<'T> -> seq<int * int * 'T> 
-        [<Obsolete("Use the 'Matrix.Generic.init' function instead")>]
-        val constDiag : int -> 'T          -> Matrix<'T>
-        [<Obsolete("Use the '+' operator instead")>]
-        val add       : Matrix<'T> -> Matrix<'T> -> Matrix<'T>
-        [<Obsolete("Use the 'initDiagonal' function instead")>]
-        val diag      : Vector<'T>        -> Matrix<'T>
-        [<Obsolete("Use the '*' operator instead")>]
-        val mul       : Matrix<'T> -> Matrix<'T> -> Matrix<'T>
-        [<Obsolete("Use the '*' operator instead")>]
-        val mulV      : Matrix<'T> -> Vector<'T> -> Vector<'T>
-        [<Obsolete("Use the '*' operator instead")>]
-        val mulRV     : RowVector<'T> -> Matrix<'T> -> RowVector<'T>
-        [<Obsolete("Use the '.*' operator instead")>]
-        val cptMul    : Matrix<'T> -> Matrix<'T> -> Matrix<'T>
-        [<Obsolete("Use the '-' operator instead")>]
-        val sub       : Matrix<'T> -> Matrix<'T> -> Matrix<'T>
-        [<Obsolete("Use the '-' prefix operator instead")>]
-        val neg       : Matrix<'T> -> Matrix<'T>
-        [<Obsolete("Use the '*' operator instead")>]
-        val scale     : 'T  -> Matrix<'T> -> Matrix<'T>
-        [<Obsolete("Use the '.Column' method instead")>]
-        val getCol  : Matrix<'T> -> int -> Vector<'T>
-        [<Obsolete("Use the '.Row' method instead")>]
-        val getRow  : Matrix<'T> -> int -> RowVector<'T>
-        [<Obsolete("Use the '.Columns' method instead")>]
-        val getCols : Matrix<'T> -> start:int -> length:int -> Matrix<'T>
-        [<Obsolete("Use the '.Rows' method instead")>]
-        val getRows : Matrix<'T> -> start:int -> length:int -> Matrix<'T>
-        [<Obsolete("Use the '.Region' method instead")>]
-        val getRegion  : Matrix<'T> -> starti:int -> startj:int -> lengthi:int -> lengthj:int -> Matrix<'T>
-        [<Obsolete("Use the '.Diagonal' method instead")>]
-        val getDiagN : Matrix<'T> -> int    -> Vector<'T>
-        [<Obsolete("Use the '.Diagonal' property instead")>]
-        val getDiag  : Matrix<'T>           -> Vector<'T>
-        [<Obsolete("This function will be removed in a future revision of this library. Just use 'compare m1 m2' instead")>]
-        val compare  : Matrix<'T> -> Matrix<'T> -> int
-        [<Obsolete("This function will be removed in a future revision of this library. Just use 'hash m' instead")>]
-        val hash     : Matrix<'T> -> int
-        [<Obsolete("This function will be removed in a future revision of this library. Set the elements of the matrix directly instead using 'm.[i,j] <- v'")>]
-        val inplace_assign       : (int -> int -> 'T) -> Matrix<'T> -> unit
-        [<Obsolete("This function will be removed in a future revision of this library. Set the elements of the matrix directly instead using 'm.[i,j] <- v'")>]
-        val inplace_mapi  : (int -> int -> 'T -> 'T) -> Matrix<'T> -> unit
-        [<Obsolete("This function will be removed in a future revision of this library. Set the elements of the matrix directly instead using 'm.[i,j] <- v'")>]
-        val inplace_cptMul : Matrix<'T> -> Matrix<'T> -> unit
-        [<Obsolete("This function will be removed in a future revision of this library. Set the elements of the matrix directly instead using 'm.[i,j] <- v'")>]
-        val inplace_scale  : 'T -> Matrix<'T> -> unit
-
-
-/// Operations to manipulate floating
-/// point column vectors. The submodule VectorOps.Generic contains a 
-/// matching set of operations to manipulate column vectors carrying
-/// arbitrary element types.
-[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
-[<RequireQualifiedAccess>]
-module Vector =
-
-    /// Get an element of a column vector
-    val get   : vector -> int -> float
-
-    /// Set an element of a column vector
-    val set   : vector -> int -> float -> unit
-
-    /// Get the dimensions (number of rows) of a column vector. Identical to <c>nrows</c>
-    val length   : vector -> int 
-
-    /// Create a vector of a fixed length using a function to compute the initial element values
-    val init  : int ->        (int -> float)        -> vector
-
-    /// Create a vector from a list of numbers
-    val ofList   : float list          -> vector
-    
-    /// Create a vector from a sequence of numbers
-    val ofSeq    : seq<float>         -> vector
-
-    /// Create a vector from an array of double precision floats
-    val ofArray  : float array         -> vector
-
-    /// Return a new array containing a copy of the elements of the given vector
-    val toArray  : vector           -> float array
-    
-    /// Create a 1-element vector
-    val ofScalar  : float              -> vector
-
-    /// Generate a vector of the given length where each entry contains the given value
-    val create    : int        -> float -> vector
-    
-    /// Return a vector of the given length where every entry is zero.
-    val zero     : int                 -> vector
-    
-    /// Create a vector that represents a mesh over the given range
-    /// e.g. rangef (-1.0) 0.5 1.0 = vector [ -1.0; -0.5; 0.0; 0.5; 1.0]
-    val rangef : float -> float -> float -> vector
-    
-    /// Create a vector that represents a integral mesh over the given range
-    /// e.g. range 1 5 = vector [ 1.;2.;3.;4.;5. ]
-    val range  : int -> int              -> vector
-      
-    ///Dot product
-    val dot       : vector -> vector -> float
-
-    ///Point-wise exponential of a vector.
-    val cptPow    : vector -> float -> vector
-
-    ///Transpose of a matrix. Use also m.Transpose
-    val transpose     :           vector -> rowvec
-
-    ///Sum all the elements of a vector
-    val sum       : vector -> float
-
-    ///Multiply all the elements of a matrix
-    val prod      : vector -> float
-
-    /// Computes the 2-norm of a vector: sqrt(x.Transpose*x).
-    val norm      : vector -> float
-
-    /// Return true if a predicate returns true for all values in a vector
-    val forall  : (float -> bool) -> vector -> bool
-
-    /// Return true if a predicate returns true for some value in a vector
-    val exists  : (float -> bool) -> vector -> bool 
-
-    /// Return true if an indexed predicate returns true for all values in a vector
-    val foralli  : (int ->        float -> bool) -> vector -> bool
-
-    /// Return true if an indexed predicate returns true for some value in a vector
-    val existsi  : (int ->        float -> bool) -> vector -> bool 
-
-    /// Fold a function over all elements of a vector
-    val fold      : ('T -> float -> 'T) -> 'T         -> vector -> 'T
-
-    /// Fold an indexed function over all elements of a vector
-    val foldi      : (int -> 'T -> float -> 'T) -> 'T         -> vector -> 'T
-
-    /// Copy a vector
-    val copy : vector -> vector
-    
-    /// Map a function over each element of a vector
-    val map  : (float -> float) -> vector -> vector
-   
-    /// Map an indexed function over each element of a vector
-    val mapi  : (int        -> float -> float) -> vector -> vector
-   
-    [<System.Obsolete("This function has been renamed. Use 'Vector.ofList' instead")>]
-    val of_list   : float list          -> vector
-    [<System.Obsolete("This function has been renamed. Use 'Vector.ofSeq' instead")>]
-    val of_seq    : seq<float>         -> vector
-    [<System.Obsolete("This function has been renamed. Use 'Vector.ofArray' instead")>]
-    val of_array  : float array         -> vector
-    [<System.Obsolete("This function has been renamed. Use 'Vector.toArray' instead")>]
-    val to_array  : vector           -> float array
-    [<System.Obsolete("This function has been renamed. Use 'Vector.ofScalar' instead")>]
-    val of_scalar  : float              -> vector
-    [<Obsolete("Use the '+' operator instead")>]
-    val add       : vector -> vector -> vector
-    [<Obsolete("Use the '-' operator instead")>]
-    val sub       : vector -> vector -> vector
-    [<Obsolete("Use the '-' prefix operator instead")>]
-    val neg       :           vector -> vector
-    [<Obsolete("This function will be removed in a future revision of this library. Set the elements of the vector directly instead using 'vec.[i] <- x'")>]
-    val inplace_assign       : (int ->        float) -> vector -> unit
-    [<Obsolete("This function will be removed in a future revision of this library. Set the elements of the vector directly instead using 'vec.[i] <- x'")>]
-    val inplace_mapi  : (int ->        float -> float) -> vector -> unit
-    [<Obsolete("This function will be removed in a future revision of this library. Set the elements of the vector directly instead using 'vec.[i] <- x'")>]
-    val inplace_add    : vector -> vector -> unit
-    [<Obsolete("This function will be removed in a future revision of this library. Set the elements of the vector directly instead using 'vec.[i] <- x'")>]
-    val inplace_sub    : vector -> vector -> unit
-    [<Obsolete("This function will be removed in a future revision of this library. Set the elements of the vector directly instead using 'vec.[i] <- x'")>]
-    val inplace_cptMul : vector -> vector -> unit
-    [<Obsolete("This function will be removed in a future revision of this library. Set the elements of the vector directly instead using 'vec.[i] <- x'")>]
-    val inplace_scale  : float -> vector -> unit
-    [<Obsolete("Use the '.*' operator instead")>]
-    val cptMul    : vector -> vector -> vector
-    [<Obsolete("Use the '*' operator instead")>]
-    val scale     : float  -> vector -> vector
-
-    
-    /// Operations to manipulate column vectors carrying
-    /// arbitrary element types. 
-    module Generic =
-        // Accessors
-
-        /// Get an element of a column vector
-        val get   : Vector<'T> -> int -> 'T
-
-        /// Set an element of a column vector
-        val set   : Vector<'T> -> int -> 'T -> unit
-
-        /// Get the dimensions (number of rows) of a column vector. Identical to <c>nrows</c>
-        val length   : Vector<'T> -> int 
-
-        /// Creation: general
-        val init  : int ->        (int -> 'T)        -> Vector<'T>
-
-        /// Creation: useful when the element type has associated operations.
-        val initNumeric  : int ->        (INumeric<'T> -> int -> 'T)        -> Vector<'T>
-
-        /// Create a vector from a list of numbers
-        val ofList   : 'T list          -> Vector<'T>
-      
-        /// Create a vector from a sequence of numbers
-        val ofSeq    : seq<'T>         -> Vector<'T>
-
-        /// Create a 1-element vector
-        val ofScalar  : 'T              -> Vector<'T>
-
-        /// Create a vector from an array of elements
-        val ofArray  : 'T[]         -> Vector<'T>
-
-        /// Return a new array containing a copy of the elements of the given vector
-        val toArray  : Vector<'T>    -> 'T[]
-
-        /// Generate a vector of the given length where each entry contains the given value
-        val create    : int        -> 'T -> Vector<'T>
-      
-        /// Return a vector of the given length where every entry is zero.
-        val zero     : int                 -> Vector<'T>
-      
-        ///Take the pointwise maximum of two vectors
-        val cptMax    : Vector<'T> -> Vector<'T> -> Vector<'T> when 'T : comparison
-
-        ///Take the pointwise minimum of two vectors
-        val cptMin    : Vector<'T> -> Vector<'T> -> Vector<'T> when 'T : comparison
-
-        ///Dot product
-        val dot       : Vector<'T> -> Vector<'T> -> 'T
-
-        ///Sum all the elements of a vector
-        val sum       : Vector<'T> -> 'T
-      
-        ///Multiply all the elements of a matrix
-        val prod      : Vector<'T> -> 'T
-
-        /// Computes the 2-norm of a vector: sqrt(x.Transpose*x).
-        val norm      : Vector<'T> -> float
-
-        /// Return true if a predicate returns true for all values in a vector
-        val forall  : predicate:('T -> bool) -> Vector<'T> -> bool
-
-        /// Return true if a predicate returns true for some value in a vector
-        val exists  : predicate:('T -> bool) -> Vector<'T> -> bool 
-
-        /// Return true if an indexed predicate returns true for all values in a vector
-        val foralli  : (int -> 'T -> bool) -> Vector<'T> -> bool
-
-        /// Return true if an indexed predicate returns true for some value in a vector
-        val existsi  : (int -> 'T -> bool) -> Vector<'T> -> bool 
-
-        /// Fold a function over all elements of a vector
-        val fold      : folder:('State -> 'T -> 'State) -> 'State -> Vector<'T> -> 'State
-
-        /// Fold an indexed function over all elements of a vector
-        val foldi      : (int -> 'State -> 'T -> 'State) -> 'State -> Vector<'T> -> 'State
-
-        /// Copy the vector
-        val copy: Vector<'T> -> Vector<'T>
-        
-        /// Map a function over each element of a vector
-        val map  : ('T -> 'T) -> Vector<'T> -> Vector<'T>
-     
-        /// Map an indexed function over each element of a vector
-        val mapi  : (int        -> 'T -> 'T) -> Vector<'T> -> Vector<'T>
-     
-
-        [<System.Obsolete("This function has been renamed. Use 'Vector.ofList' instead")>]
-        val of_list   : 'T list          -> Vector<'T>
-        [<System.Obsolete("This function has been renamed. Use 'Vector.ofSeq' instead")>]
-        val of_seq    : seq<'T>         -> Vector<'T>
-        [<System.Obsolete("This function has been renamed. Use 'Vector.ofScalar' instead")>]
-        val of_scalar  : 'T              -> Vector<'T>
-        [<System.Obsolete("This function has been renamed. Use 'Vector.ofArray' instead")>]
-        val of_array  : 'T[]         -> Vector<'T>
-        [<System.Obsolete("This function has been renamed. Use 'Vector.toArray' instead")>]
-        val to_array  : Vector<'T>    -> 'T[]
-        [<Obsolete("Use the .* operator instead")>]
-        val cptMul    : Vector<'T> -> Vector<'T> -> Vector<'T>      
-        [<Obsolete("Use the 'vector.Transpose' property instead")>]
-        val transpose : Vector<'T> -> RowVector<'T>
-        [<Obsolete("Use the '+' operator instead")>]
-        val add       : Vector<'T> -> Vector<'T> -> Vector<'T>
-        [<Obsolete("Use the '-' operator instead")>]
-        val sub       : Vector<'T> -> Vector<'T> -> Vector<'T>
-        [<Obsolete("Use the '-' prefix operator instead")>]
-        val neg       : Vector<'T> -> Vector<'T>
-        [<Obsolete("Use the '*' operator instead")>]
-        val scale     : 'T  -> Vector<'T> -> Vector<'T>
-        [<Obsolete("This function will be removed in a future revision of this library. Set the elements of the vector directly instead using 'vec.[i] <- x'")>]
-        val inplace_assign : (int -> 'T) -> Vector<'T> -> unit
-        [<Obsolete("This function will be removed in a future revision of this library. Set the elements of the vector directly instead using 'vec.[i] <- x'")>]
-        val inplace_mapi  : (int -> 'T -> 'T) -> Vector<'T> -> unit
-        [<Obsolete("This function will be removed in a future revision of this library. Set the elements of the vector directly instead using 'vec.[i] <- x'")>]
-        val inplace_add    : Vector<'T> -> Vector<'T> -> unit
-        [<Obsolete("This function will be removed in a future revision of this library. Set the elements of the vector directly instead using 'vec.[i] <- x'")>]
-        val inplace_sub    : Vector<'T> -> Vector<'T> -> unit
-        [<Obsolete("This function will be removed in a future revision of this library. Set the elements of the vector directly instead using 'vec.[i] <- x'")>]
-        val inplace_cptMul : Vector<'T> -> Vector<'T> -> unit
-        [<Obsolete("This function will be removed in a future revision of this library. Set the elements of the vector directly instead using 'vec.[i] <- x'")>]
-        val inplace_scale  : 'T -> Vector<'T> -> unit
-
-
-
-/// Operations to manipulate floating
-/// point row vectors. These are included for completeness and are
-/// nearly always transposed to column vectors.
-[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
-[<RequireQualifiedAccess>]
-module RowVector =
-
-    /// Get an element of a column vector
-    val get   : rowvec -> int -> float
-
-    /// Set an element of a column rowvec
-    val set   : rowvec -> int -> float -> unit
-
-    /// Get the dimensions (number of rows) of a column rowvec. 
-    val length   : rowvec -> int 
-
-    /// Create by constant initialization
-    val create : int -> float  -> rowvec
-
-    /// Create by comprehension
-    val init : int ->  (int -> float) -> rowvec
-
-    /// Return a vector of the given length where every entry is zero.
-    val zero     : int -> rowvec
-
-    // Transpose the row vector
-    val transpose : rowvec -> vector
-
-    // Copy the row vector
-    val copy : rowvec -> rowvec
-
-    /// Create a vector from a list of numbers
-    val ofList   : float list          -> rowvec
-
-    /// Create a vector from a sequence of numbers
-    val ofSeq    : seq<float>         -> rowvec
-
-    /// Create a vector from an array of double precision floats
-    val ofArray  : float array         -> rowvec
-
-    /// Return a new array containing a copy of the elements of the given vector
-    val toArray  : rowvec              -> float array
-    
-    [<System.Obsolete("This function has been renamed. Use 'RowVector.ofList' instead")>]
-    val of_list   : float list          -> rowvec
-    [<System.Obsolete("This function has been renamed. Use 'RowVector.ofSeq' instead")>]
-    val of_seq    : seq<float>         -> rowvec
-    [<System.Obsolete("This function has been renamed. Use 'RowVector.ofArray' instead")>]
-    val of_array  : float array         -> rowvec
-    [<System.Obsolete("This function has been renamed. Use 'RowVector.toArray' instead")>]
-    val to_array  : rowvec              -> float array
-    
-    
-    /// Operations to manipulate row vectors types carrying
-    /// arbitrary element types. 
-    module Generic =
-        // Accessors
-
-        /// Get an element from a column vector. 
-        val get   : RowVector<'T> -> int -> 'T
-        /// Set an element in a column vector. 
-        val set   : RowVector<'T> -> int -> 'T -> unit
-        /// Get the number of rows in a column vector. 
-        val length: RowVector<'T> -> int 
-        /// Transpose the row vector
-        val transpose        : RowVector<'T>  -> Vector<'T> 
-        /// Create by comprehension
-        val init       : int ->        (int -> 'T)        -> RowVector<'T> 
-        /// Create by constant initialization
-        val create       : int ->      'T  -> RowVector<'T> 
-        /// Return a vector of the given length where every entry is zero.
-        val zero     : int                 -> RowVector<'T>
-        /// Create a row vector from a list of elements
-        val ofList   : 'T list          -> RowVector<'T> 
-        /// Create a row vector from a sequence of elements
-        val ofSeq    : seq<'T>         -> RowVector<'T> 
-
-        /// Create a row vector from an array of elements
-        val ofArray  : 'T[]         -> RowVector<'T>
-
-        /// Return a new array containing a copy of the elements of the given vector
-        val toArray  : RowVector<'T>    -> 'T[]         
-
-        // Copy the row vector
-        val copy    :   RowVector<'T> -> RowVector<'T>
-
-        [<System.Obsolete("This function has been renamed. Use 'RowVector.Generic.ofList' instead")>]
-        val of_list   : 'T list          -> RowVector<'T> 
-        [<System.Obsolete("This function has been renamed. Use 'RowVector.Generic.ofSeq' instead")>]
-        val of_seq    : seq<'T>         -> RowVector<'T> 
-        [<System.Obsolete("This function has been renamed. Use 'RowVector.Generic.ofArray' instead")>]
-        val of_array  : 'T[]         -> RowVector<'T>
-        [<System.Obsolete("This function has been renamed. Use 'RowVector.Generic.toArray' instead")>]
-        val to_array  : RowVector<'T>    -> 'T[]         
-
-[<AutoOpen>]
-module MatrixTopLevelOperators = 
-    /// Builds a matrix from a sequence of sequence of floats.
-    val matrix : seq<#seq<float>> -> matrix
-    /// Builds a (column) vector from a sequence of floats.
-    val vector : seq<float> -> vector
-    /// Builds a (row) vector from a sequence of floats.
-    val rowvec : seq<float> -> rowvec
-
+// (c) Microsoft Corporation 2005-2009. 
+
+namespace Microsoft.FSharp.Math
+
+open Microsoft.FSharp.Math
+open System
+open System.Collections
+open System.Collections.Generic
+
+/// The type of matrices. The arithmetic operations on the element type are determined by inspection on the element type itself.
+/// Two representations are supported: sparse and dense. 
+[<Sealed>]
+type Matrix<'T> = 
+
+    /// Get the number of rows in a matrix
+    member NumRows : int
+
+    /// Get the number of columns in a matrix
+    member NumCols : int
+
+    /// Get the number of (rows,columns) in a matrix
+    member Dimensions : int * int
+
+    /// Get the item at the given position in a matrix
+    member Item : int * int -> 'T with get,set
+
+    /// Supports the slicing syntax 'A.[idx1..idx2,idx1..idx2]'
+    member GetSlice : start1:int option * finish1:int option * start2:int option * finish2:int option -> Matrix<'T>
+
+    /// Supports the slicing syntax 'A.[idx1..idx2,idx1..idx2] <- B'
+    member SetSlice : start1:int option * finish1:int option * start2:int option * finish2:int option * source:Matrix<'T> -> unit
+    
+    /// Retrieve the dictionary of numeric operations associated with the element
+    /// type of this matrix. Accessing the property may raise an NotSupportedException if the element
+    /// type doesn't support any numeric operations. The object returned
+    /// may support additional numeric operations such as IFractional: 
+    /// this can be determined by a dynamic type test against the object
+    /// returned.
+    member ElementOps : INumeric<'T>
+
+    /// Point-wise addition of two matrices. An InvalidArgument exception will be
+    /// raised if the dimensions do not match.
+    static member ( +  ) : Matrix<'T> * Matrix<'T> -> Matrix<'T>
+
+    /// Point-wise subtraction of two matrices. An InvalidArgument exception will be
+    /// raised if the dimensions do not match.
+    static member ( -  ) : Matrix<'T> * Matrix<'T> -> Matrix<'T>
+
+    /// Matrix negation. 
+    static member ( ~- ) : Matrix<'T>              -> Matrix<'T>
+
+    /// Prefix '+' operator. A nop.
+    static member ( ~+ ) : Matrix<'T>              -> Matrix<'T>
+
+    /// Matrix multiplication. An InvalidArgument exception will be
+    /// raised if the dimensions do not match.
+    static member ( * ) : Matrix<'T> * Matrix<'T> -> Matrix<'T>
+
+    /// Matrix-vector multiplication. 
+    static member ( * ) : Matrix<'T> * Vector<'T> -> Vector<'T>
+
+    /// Multiply each element of a matrix by the given scalar value
+    static member ( * ) : Matrix<'T> * 'T          -> Matrix<'T>
+
+    /// Point-wise matrix multiplication. An InvalidArgument exception will be
+    /// raised if the dimensions do not match.
+    static member ( .* ) : Matrix<'T> * Matrix<'T>  -> Matrix<'T>
+
+    /// Multiply each element of a matrix by a scalar value
+    static member ( * ) : 'T          * Matrix<'T> -> Matrix<'T>
+    
+    /// Get the transpose of a matrix.
+    member Transpose : Matrix<'T>
+    
+    /// Permutes the rows of a matrix.
+    member PermuteRows : permutation:(int -> int) -> Matrix<'T>
+    
+    /// Permutes the columns of a matrix.
+    member PermuteColumns : permutation:(int -> int) -> Matrix<'T>
+
+
+    //interface IMatrix<'T>
+    interface IComparable
+    interface IStructuralComparable
+    interface IStructuralEquatable
+    interface IEnumerable<'T>
+    override GetHashCode : unit -> int
+    override Equals : obj -> bool
+  
+    /// Return a new array containing the elements of a matrix
+    member ToArray2D : unit -> 'T[,]  
+
+    /// Return the non-zero entries of a sparse or dense matrix
+    member NonZeroEntries: seq<int * int * 'T> 
+
+    /// Convert a matrix to a row vector
+    member ToRowVector : unit -> RowVector<'T>                 
+
+    /// Convert a matrix to a column vector
+    member ToVector : unit -> Vector<'T> 
+
+    /// Returns sqrt(sum(norm(x)*(norm(x))) of all the elements of a matrix.
+    /// The element type of a matrix must have an associated instance of INormFloat<'T> (see <c>GlobalAssociations</c>) ((else NotSupportedException)).
+    member Norm : float
+
+    /// Select a column from a matrix
+    member Column : index:int -> Vector<'T>
+
+    /// Select a row from a matrix
+    member Row :  index:int -> RowVector<'T>
+
+    /// Select a range of columns from a matrix
+    member Columns : start:int  * length:int -> Matrix<'T>
+
+    /// Select a range of rows from a matrix
+    member Rows : start:int * length:int -> Matrix<'T>
+
+    /// Select a region from a matrix
+    member Region : starti:int * startj:int * lengthi:int * lengthj:int -> Matrix<'T>
+
+
+    /// Return the nth diagonal of a matrix, as a vector. Diagonal 0 is the primary
+    /// diagonal, positive diagonals are further to the upper-right of a matrix.
+    member GetDiagonal : int -> Vector<'T>
+
+    /// Get the main diagonal of a matrix, as a vector
+    member Diagonal : Vector<'T>
+
+    /// Create a new matrix that is a copy of an array
+    member Copy : unit -> Matrix<'T>
+
+    /// Get the internal array of values for a dense matrix. This property 
+    /// should only be used when interoperating with other matrix libraries.
+    member InternalDenseValues : 'T[,]
+    /// Get the internal array of values for a sparse matrix. This property 
+    /// should only be used when interoperating with other matrix libraries.
+    member InternalSparseValues : 'T[]
+    /// Get the internal array of row offsets for a sparse matrix. This property 
+    /// should only be used when interoperating with other matrix libraries.
+    member InternalSparseRowOffsets : int[]
+    /// Get the internal array of column values for a sparse matrix. This property 
+    /// should only be used when interoperating with other matrix libraries.
+    member InternalSparseColumnValues : int[]
+
+    /// Indicates if a matrix uses the sparse representation.
+    member IsSparse : bool
+
+    /// Indicates if a matrix uses the dense representation.
+    member IsDense : bool
+
+    [<System.Obsolete("This member has been renamed to 'ToArray2D'")>]
+    member ToArray2 : unit -> 'T[,]  
+
+    member StructuredDisplayAsArray : obj
+
+/// The type of column vectors. The arithmetic operations on the element type are determined by inspection 
+/// on the element type itself
+and 
+
+  [<Sealed>]
+  Vector<'T> = 
+
+
+    /// Get the underlying internal array of values for a vector. This property 
+    /// should only be used when interoperating with other matrix libraries.
+    member InternalValues : 'T[]
+
+    /// Gets the number of entries in a vector
+    member Length : int
+
+    /// Gets the number of rows in a vector
+    member NumRows : int
+
+    /// Gets an item from a vector
+    member Item : int -> 'T with get,set
+
+    /// Gets the element operations for the element type of a vector, if any
+    member ElementOps : INumeric<'T>
+    
+    /// Supports the slicing syntax 'v.[idx1..idx2]'
+    member GetSlice      : start:int option * finish:int option -> Vector<'T>
+
+    /// Supports the slicing syntax 'v.[idx1..idx2] <- v2'
+    member SetSlice      : start:int option * finish:int option * source:Vector<'T> -> unit
+
+    /// Add two vectors, pointwise
+    static member ( +  ) : Vector<'T>    * Vector<'T> -> Vector<'T>
+
+    /// Subtract two vectors, pointwise
+    static member ( -  ) : Vector<'T>    * Vector<'T> -> Vector<'T>
+
+    /// Negate a vector
+    static member ( ~- ) : Vector<'T>                  -> Vector<'T>
+
+    /// Return the input vector 
+    static member ( ~+ ) : Vector<'T>                  -> Vector<'T>
+
+    /// Point-wise multiplication of two vectors.
+    static member ( .* ) : Vector<'T>    * Vector<'T> -> Vector<'T>
+
+    /// Multiply each element of a vector by a scalar value.
+    static member ( * ) : 'T             * Vector<'T> -> Vector<'T>
+
+    /// Multiply a column vector and a row vector to produce a matrix
+    static member ( * )   : Vector<'T>    * RowVector<'T> -> Matrix<'T>
+
+    /// Multiply a vector by a scalar
+    static member ( * )   : Vector<'T>    * 'T          -> Vector<'T>
+
+    /// Get the transpose of a vector.
+    member Transpose : RowVector<'T>
+    
+    /// Permute the elements of a vector.
+    member Permute : permutation:(int -> int) -> Vector<'T>    
+    
+    interface IComparable
+    interface IStructuralComparable
+    interface IStructuralEquatable
+    interface IEnumerable<'T>
+    override GetHashCode : unit -> int
+    override Equals : obj -> bool
+
+    /// Return a new array containing a copy of the elements of a vector
+    member ToArray : unit    -> 'T[]
+
+    /// Computes the 2-norm of a vector: sqrt(x.Transpose*x).
+    member Norm : float
+
+    /// Create a new matrix that is a copy of a array
+    member Copy : unit -> Vector<'T>
+
+    member StructuredDisplayAsArray : 'T[]
+
+
+
+
+/// The type of row vectors. 
+and [<Sealed>]
+    RowVector<'T> =
+
+    /// Get the underlying internal array of values for a vector. This property 
+    /// should only be used when interoperating with other matrix libraries.
+    member InternalValues : 'T[]
+
+    // Basic access
+    member Length : int
+    member NumCols : int
+    member Item : int -> 'T with get,set
+    member ElementOps : INumeric<'T>
+
+    /// Supports the slicing syntax 'rv.[idx1..idx2]'
+    member GetSlice      : start:int option * finish:int option -> RowVector<'T>
+
+    /// Supports the slicing syntax 'rv.[idx1..idx2] <- rv2'
+    member SetSlice      : start:int option * finish:int option * source:RowVector<'T> -> unit
+
+
+    /// Point-wise addition of two row vectors
+    static member ( +  )  : RowVector<'T>    * RowVector<'T> -> RowVector<'T>
+
+    /// Point-wise subtraction of two row vectors
+    static member ( -  )  : RowVector<'T>    * RowVector<'T> -> RowVector<'T>
+
+    /// Point-wise negation of a row vector
+    static member ( ~- )  : RowVector<'T>                  -> RowVector<'T>
+
+    /// Return a row vector, unchanged
+    static member ( ~+ )  : RowVector<'T>                  -> RowVector<'T>
+
+    /// Point-wise multiplication of two row vectors
+    static member ( .* )  : RowVector<'T> * RowVector<'T>    -> RowVector<'T>
+    
+    /// Multiply a row vector by a vector
+    static member ( * ) : RowVector<'T> * Vector<'T>    -> 'T
+
+    /// Multiply a row vector by a matrix
+    static member ( * )   : RowVector<'T> * Matrix<'T>    -> RowVector<'T>
+
+    /// Multiply a row vector by a scalar
+    static member ( * )   : RowVector<'T> * 'T            -> RowVector<'T>
+
+    /// Multiply a scalar by a row vector
+    static member ( * )  : 'T            * RowVector<'T>    -> RowVector<'T>
+
+    /// Get the transpose of the row vector.
+    member Transpose : Vector<'T>
+    
+    /// Permute the elements of the row vector.
+    member Permute : permutation:(int -> int) -> RowVector<'T>  
+
+    interface IComparable
+    interface IStructuralComparable
+    interface IStructuralEquatable
+    interface IEnumerable<'T>
+    override GetHashCode : unit -> int
+    override Equals : obj -> bool
+
+    /// Return a new array containing a copy of the elements of a vector
+    member ToArray : unit    -> 'T[]
+
+    /// Create a new matrix that is a copy of a array
+    member Copy : unit -> RowVector<'T>
+
+    member StructuredDisplayAsArray : 'T[]
+  
+/// The type of floating point matrices
+type matrix = Matrix<float>
+/// The type of floating point column vectors
+type vector = Vector<float>
+/// The type of floating point row vectors
+type rowvec = RowVector<float>
+
+/// Operations to manipulate floating
+/// point matrices. The submodule <c>Matrix.Generic</c> contains a 
+/// matching set of operations to manipulate matrix types carrying
+/// arbitrary element types.
+[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+[<RequireQualifiedAccess>]
+module Matrix =
+
+
+    /// Get an element of a matrix
+    val get : matrix -> int -> int -> float
+
+    /// Set an element of a matrix
+    val set : matrix -> int -> int -> float -> unit
+
+    // Creation: general
+    val init  : int -> int -> (int -> int -> float) -> matrix
+
+    /// Create a matrix with all entries the given constant
+    val create : int -> int -> float -> matrix
+    
+    /// Create a dense representation matrix with the given entries. 
+    val initDense : int -> int -> seq<int * int * float> -> matrix
+
+    /// Create a sparse representation matrix with the given entries. Not all 
+    /// operations are available for sparse matrices, and mutation is not permitted.
+    /// If an operation on sparse matrices raises a runtime exception then consider 
+    /// converting to a dense matrix using to_dense.
+    val initSparse : int -> int -> seq<int * int * float> -> matrix
+
+    /// Create a matrix with all entries zero
+    val zero     : int -> int          -> matrix
+    
+    /// Create a square matrix with the constant 1.0 lying on diagonal
+    val identity      : int -> matrix
+
+    /// Create a square matrix with a vector lying on diagonal
+    val initDiagonal : vector -> matrix
+    
+    /// Create a matrix from the given data
+    val ofList   : float list list     -> matrix
+
+    /// Create a matrix from the given data
+    val ofSeq    : seq<#seq<float>>   -> matrix
+
+    /// Create a matrix from the given data
+    val ofArray2D : float[,]            -> matrix
+
+    /// Return a new array containing the elements of the given matrix
+    val toArray2D : matrix              -> float[,]
+
+
+    /// Create a 1x1 matrix containing the given value 
+    val ofScalar : float               -> matrix
+    /// Create a matrix with one row from the given row vector
+    val ofRowVector : rowvec              -> matrix
+    /// Create a matrix with one column from the given vector
+    val ofVector : vector              -> matrix
+
+    /// Return the element at row 0, column 0 of a matrix
+    val toScalar : matrix              -> float                
+    /// Return the first row of a matrix
+    val toRowVector : matrix              -> rowvec                
+    /// Return the first column of a matrix
+    val toVector : matrix              -> vector
+    /// Ensure that a matrix uses dense representation
+    val toDense  : matrix              -> matrix
+
+    /// Point-wise maximum element of two matrices
+    val cptMax    : matrix -> matrix -> matrix
+    
+    /// Point-wise minimum element of two matrices
+    val cptMin    : matrix -> matrix -> matrix
+    
+    /// Add two matrices (operator +)
+    val add       : matrix -> matrix -> matrix
+
+    /// Dot product
+    val dot       : matrix -> matrix -> float
+
+    /// Point-wise exponential of a matrix.
+    val cptPow       : matrix -> float -> matrix
+
+    /// Transpose of a matrix. Use also m.Transpose
+    val transpose     :           matrix -> matrix
+
+    /// Sum of the diagonal elements of a matrix
+    val trace     : matrix -> float
+    
+    /// Generate a new matrix of the same size as the input with random entries 
+    /// drawn from the range 0..aij. Random numbers are generated using a globally 
+    /// shared System.Random instance with the initial seed 99.
+    val randomize : matrix -> matrix
+
+    /// Sum all the elements of a matrix
+    val sum       : matrix -> float
+
+    ///Multiply all the elements of a matrix
+    val prod      : matrix -> float
+
+    ///sqrt(sum(x*x)) of all the elements of a matrix
+    val norm      : matrix -> float
+
+    /// Check if a predicate holds for all elements of a matrix
+    val forall  : (float -> bool) -> matrix -> bool
+
+    /// Check if a predicate holds for at least one element of a matrix
+    val exists  : (float -> bool) -> matrix -> bool 
+
+    /// Check if a predicate holds for all elements of a matrix
+    val foralli  : (int -> int -> float -> bool) -> matrix -> bool
+
+    /// Check if a predicate holds for at least one element of a matrix
+    val existsi  : (int -> int -> float -> bool) -> matrix -> bool 
+
+    /// Fold a function over all elements of a matrix
+    val fold      : ('T -> float -> 'T) -> 'T         -> matrix -> 'T
+
+    /// Fold an indexed function over all elements of a matrix
+    val foldi      : (int -> int -> 'T -> float -> 'T) -> 'T         -> matrix -> 'T
+
+    /// Fold a function down each column of a matrix
+    val foldByCol : ('T -> float -> 'T) -> RowVector<'T> -> matrix -> RowVector<'T>
+
+    /// Fold a function along each row of a matrix
+    val foldByRow : ('T -> float -> 'T) -> Vector<'T> -> matrix -> Vector<'T>
+
+    /// Fold a function along a particular column of a matrix
+    val foldCol   : ('T -> float -> 'T) -> 'T         -> matrix -> int -> 'T 
+
+    /// Fold a function down a particular row of a matrix
+    val foldRow   : ('T -> float -> 'T) -> 'T         -> matrix -> int -> 'T
+    
+    /// Map a function over each element of a matrix, producing a new matrix
+    val map  : (float -> float) -> matrix -> matrix
+   
+    /// Map the given indexed function over each element of a matrix, producing a new matrix
+    val mapi  : (int -> int -> float -> float) -> matrix -> matrix
+   
+    /// Create a new matrix that is a copy of the given array
+    val copy : matrix -> matrix
+   
+    /// In-place addition, mutating the first matrix argument.
+    val inplaceAdd    : matrix -> matrix -> unit
+
+    /// In-place subtraction, mutating the first matrix argument. 
+    val inplaceSub    : matrix -> matrix -> unit
+
+    [<Obsolete("Use the '.NonZeroEntries' property instead")>]
+    val nonzero_entries : matrix -> seq<int * int * float>         
+    [<System.Obsolete("This function has been renamed. Use 'Matrix.inplaceAdd' instead")>]
+    val inplace_add    : matrix -> matrix -> unit
+    [<System.Obsolete("This function has been renamed. Use 'Matrix.inplaceSub' instead")>]
+    val inplace_sub    : matrix -> matrix -> unit
+    [<System.Obsolete("This function has been renamed. Use 'Matrix.ofList' instead")>]
+    val of_list   : float list list     -> matrix
+    [<System.Obsolete("This function has been renamed. Use 'Matrix.ofSeq' instead")>]
+    val of_seq    : seq<#seq<float>>   -> matrix
+    [<System.Obsolete("This function has been renamed. Use 'Matrix.ofArray2D' instead")>]
+    val inline of_array2D : float[,]            -> matrix
+    [<System.Obsolete("This function has been renamed. Use 'Matrix.toArray2D' instead")>]
+    val inline to_array2D : matrix              -> float[,]
+    [<System.Obsolete("This function has been renamed. Use 'Matrix.ofScalar' instead")>]
+    val of_scalar : float               -> matrix
+    [<System.Obsolete("This function has been renamed. Use 'Matrix.ofRowVector' instead")>]
+    val of_rowvec : rowvec              -> matrix
+    [<System.Obsolete("This function has been renamed. Use 'Matrix.ofVector' instead")>]
+    val of_vector : vector              -> matrix
+    [<System.Obsolete("This function has been renamed. Use 'Matrix.toScalar' instead")>]
+    val to_scalar : matrix              -> float                
+    [<System.Obsolete("This function has been renamed. Use 'Matrix.toRowVector' instead")>]
+    val to_rowvec : matrix              -> rowvec                
+    [<System.Obsolete("This function has been renamed. Use 'Matrix.toVector' instead")>]
+    val to_vector : matrix              -> vector
+    [<System.Obsolete("This function has been renamed. Use 'Matrix.toDense' instead")>]
+    val to_dense  : matrix              -> matrix
+    [<Obsolete("Use the '*' operator instead")>]
+    val mul       : matrix -> matrix -> matrix
+    [<Obsolete("This function has been renamed to 'initDiagonal'")>]
+    val init_diagonal : vector -> matrix
+    [<Obsolete("Use the 'Matrix.init' function instead")>]
+    val constDiag : int -> float        -> matrix
+    [<Obsolete("Use the 'initDiagonal' function instead")>]
+    val diag      : vector -> matrix
+    [<Obsolete("This function has been renamed to 'initDense'")>]
+    val init_dense : int -> int -> seq<int * int * float> -> matrix
+    [<Obsolete("This function has been renamed to 'initSparse'")>]
+    val init_sparse : int -> int -> seq<int * int * float> -> matrix
+    [<Obsolete("Use the '.*' operator instead")>]
+    val cptMul    : matrix -> matrix -> matrix
+    [<Obsolete("Use the '*' operator instead")>]
+    val mulV      : matrix -> vector -> vector
+    [<Obsolete("Use the '*' operator instead")>]
+    val mulRV     : rowvec -> matrix -> rowvec
+    [<Obsolete("Use the '-' operator instead")>]
+    val sub       : matrix -> matrix -> matrix
+    [<Obsolete("Use the '-' prefix operator instead")>]
+    val neg       :           matrix -> matrix
+    [<Obsolete("Use the '*' operator instead")>]
+    val scale     : float  -> matrix -> matrix
+    [<Obsolete("Use the '.Column' method instead")>]
+    val getCol  : matrix -> int -> vector
+    [<Obsolete("Use the '.Row' method instead")>]
+    val getRow  : matrix -> int -> rowvec
+    [<Obsolete("Use the '.Columns' method instead")>]
+    val getCols : matrix -> start:int -> length:int -> matrix
+    [<Obsolete("Use the '.Rows' method instead")>]
+    val getRows : matrix -> start:int -> length:int -> matrix
+    [<Obsolete("Use the '.Region' method instead")>]
+    val getRegion  : matrix -> starti:int -> startj:int -> lengthi:int -> lengthj:int -> matrix
+    [<Obsolete("Use the '.Diagonal' method instead")>]
+    val getDiagN : matrix -> int    -> vector
+    [<Obsolete("Use the '.Diagonal' property instead")>]
+    val getDiag  : matrix           -> vector
+    [<Obsolete("This function will be removed in a future revision of this library. Set the elements of the matrix directly instead using 'm.[i,j] <- v'")>]
+    val inplace_assign       : (int -> int -> float) -> matrix -> unit
+    [<Obsolete("This function will be removed in a future revision of this library. Set the elements of the matrix directly instead using 'm.[i,j] <- v'")>]
+    val inplace_mapi  : (int -> int -> float -> float) -> matrix -> unit
+    [<Obsolete("This function will be removed in a future revision of this library. Set the elements of the matrix directly instead using 'm.[i,j] <- v'")>]
+    val inplace_cptMul : matrix -> matrix -> unit
+    [<Obsolete("This function will be removed in a future revision of this library. Set the elements of the matrix directly instead using 'm.[i,j] <- v'")>]
+    val inplace_scale  : float -> matrix -> unit
+
+    /// Operations to manipulate matrix types carrying
+    /// arbitrary element types. The names and types of the operations match those
+    /// in the containing module Math.Matrix. 
+    ///
+    /// The numeric operations on the element type (add, zero etc.) are inferred from the type
+    /// argument itself. That is, for some operations 
+    /// the element type of a matrix must have an associated instance of INumeric<'T> 
+    /// or some more specific numeric association (see <c>GlobalAssociations</c>) ((else NotSupportedException)).
+    [<RequireQualifiedAccess>]
+    module Generic =
+
+        /// Get an element from a matrix. The indexes are given in row/column order.
+        val get   : Matrix<'T> -> int -> int -> 'T
+        /// Set an element in a matrix. The indexes are given in row/column order.
+        val set   : Matrix<'T> -> int -> int -> 'T -> unit
+
+        /// Create a matrix from the given data  
+        val ofList      : 'T list list       -> Matrix<'T>
+
+        /// Create a matrix from the given data  
+        val ofSeq       : seq<#seq<'T>>     -> Matrix<'T>
+
+        /// Create a matrix from the given data  
+        val ofArray2D    : 'T[,]              -> Matrix<'T>
+
+        /// Return a new array containing the elements of the given matrix
+        val toArray2D : Matrix<'T>         -> 'T[,]  
+
+        /// Create a matrix containing the given value at every element.
+        val create     : int -> int -> 'T   -> Matrix<'T>
+
+        /// Create a dense matrix from the given sequence of elements
+        val initDense : int -> int -> seq<int * int * 'T>  -> Matrix<'T>
+
+        /// Create a sparse matrix from the given sequence of elements
+        val initSparse : int -> int -> seq<int * int * 'T>  -> Matrix<'T>
+
+        /// Create a 1x1 matrix containing the given value 
+        val ofScalar    : 'T                 -> Matrix<'T>
+
+        /// Create a matrix from a row vector
+        val ofRowVector  : RowVector<'T>     -> Matrix<'T>
+        /// Create a matrix from a column vector
+        val ofVector  : Vector<'T>        -> Matrix<'T>
+
+        /// Get the element at column zero, row zero
+        val toScalar : Matrix<'T>         -> 'T                
+        /// Extract the first row of a matrix
+        val toRowVector : Matrix<'T>         -> RowVector<'T>                 
+        /// Extract the first column of a matrix
+        val toVector : Matrix<'T>         -> Vector<'T> 
+
+
+        /// Create a matrix using a function to compute the item at each index.
+        val init : int -> int -> (int -> int -> 'T) -> Matrix<'T>
+
+        /// Create a matrix using a function to compute the item at each index.
+        /// The element type of a matrix must have an associated instance of INumeric<'T> (see <c>GlobalAssociations</c>) ((else NotSupportedException)).
+        /// The function is passed the dictionary of associated operations in addition to the index pair.
+        val initNumeric  : int -> int -> (INumeric<'T> -> int -> int -> 'T)        -> Matrix<'T>
+
+        /// Create a matrix containing the zero element at each index.
+        /// The element type of a matrix must have an associated instance of INumeric<'T> (see <c>GlobalAssociations</c>) ((else NotSupportedException)).
+        val zero      : int -> int         -> Matrix<'T>
+
+        /// Create a square matrix with the one for the element type lying on diagonal
+        /// The element type of a matrix must have an associated instance of INumeric<'T> (see <c>GlobalAssociations</c>) ((else NotSupportedException)).
+        val identity      : int -> Matrix<'T>
+
+        /// Create a matrix containing the given vector along the diagonal.
+        /// The element type of a matrix must have an associated instance of INumeric<'T> (see <c>GlobalAssociations</c>) ((else NotSupportedException)).
+        val initDiagonal : Vector<'T>        -> Matrix<'T>
+
+        ///Take the pointwise maximum of two matrices
+        val cptMax    : Matrix<'T> -> Matrix<'T> -> Matrix<'T> when 'T : comparison
+
+        ///Take the pointwise maximum of two matrices
+        val cptMin    : Matrix<'T> -> Matrix<'T> -> Matrix<'T> when 'T : comparison
+
+        /// Sum of the point-wise multiple of the two matrices.
+        /// The element type of a matrix must have an associated instance of INumeric<'T> (see <c>GlobalAssociations</c>) ((else NotSupportedException)).
+        val dot       : Matrix<'T> -> Matrix<'T> -> 'T
+
+
+        /// Return a new matrix which is the transpose of the input matrix
+        val transpose : Matrix<'T> -> Matrix<'T>
+
+        /// Compute the sum of the diagonal of a square matrix
+        val trace     : Matrix<'T> -> 'T
+        /// Compute the sum of the elements in a matrix
+        val sum       : Matrix<'T> -> 'T
+        /// Compute the product of the elements in a matrix
+        val prod      : Matrix<'T> -> 'T
+        /// Returns sqrt(sum(norm(x)*(norm(x))) of all the elements of a matrix.
+        /// The element type of a matrix must have an associated instance of INormFloat<'T> (see <c>GlobalAssociations</c>) ((else NotSupportedException)).
+        val norm      : Matrix<'T> -> float
+
+        /// Fold a function over all elements of a matrix
+        val fold  : folder:('State -> 'T -> 'State) -> 'State -> Matrix<'T> -> 'State
+
+        /// Fold an indexed function over all elements of a matrix
+        val foldi  : (int -> int -> 'State -> 'T -> 'State) -> 'State -> Matrix<'T> -> 'State
+
+        /// Return true if a predicate returns true for all values in a matrix
+        val forall: ('T -> bool)           -> Matrix<'T> -> bool
+
+        /// Return true if a predicate returns true for some value in a matrix
+        val exists: ('T -> bool)           -> Matrix<'T> -> bool 
+
+        /// Return true if an indexed predicate returns true for all values in a matrix
+        val foralli: (int -> int -> 'T -> bool)           -> Matrix<'T> -> bool
+
+        /// Return true if an indexed predicate returns true for some value in a matrix
+        val existsi: (int -> int -> 'T -> bool)           -> Matrix<'T> -> bool 
+
+        /// Create a new matrix that is a copy of the given array
+        val copy : Matrix<'T> -> Matrix<'T>
+   
+        /// Map a function over a matrix
+        val map   : ('T -> 'T) -> Matrix<'T> -> Matrix<'T>
+
+        /// Map the given position-indexed function over a matrix
+        val mapi  : (int -> int -> 'T -> 'T) -> Matrix<'T> -> Matrix<'T>
+
+        /// Add the second matrix to the first by, mutating the first
+        val inplaceAdd    : Matrix<'T> -> Matrix<'T> -> unit
+        /// Subtract the second matrix from the first, by mutating the first
+        val inplaceSub    : Matrix<'T> -> Matrix<'T> -> unit
+
+        [<System.Obsolete("This function has been renamed. Use 'Matrix.Generic.inplaceAdd' instead")>]
+        val inplace_add    : Matrix<'T> -> Matrix<'T> -> unit
+        [<System.Obsolete("This function has been renamed. Use 'Matrix.Generic.inplaceSub' instead")>]
+        val inplace_sub    : Matrix<'T> -> Matrix<'T> -> unit
+        [<System.Obsolete("This function has been renamed. Use 'Matrix.Generic.ofList' instead")>]
+        val of_list      : 'T list list       -> Matrix<'T>
+        [<System.Obsolete("This function has been renamed. Use 'Matrix.Generic.ofSeq' instead")>]
+        val of_seq       : seq<#seq<'T>>     -> Matrix<'T>
+        [<System.Obsolete("This function has been renamed. Use 'Matrix.Generic.ofArray2D' instead")>]
+        val inline of_array2D    : 'T[,]              -> Matrix<'T>
+        [<System.Obsolete("This function has been renamed. Use 'Matrix.Generic.toArray2D' instead")>]
+        val inline to_array2D : Matrix<'T>         -> 'T[,]  
+        [<System.Obsolete("This function has been renamed. Use 'Matrix.Generic.ofScalar' instead")>]
+        val of_scalar    : 'T                 -> Matrix<'T>
+        [<System.Obsolete("This function has been renamed. Use 'Matrix.Generic.ofRowVector' instead")>]
+        val of_rowvec  : RowVector<'T>     -> Matrix<'T>
+        [<System.Obsolete("This function has been renamed. Use 'Matrix.Generic.ofVector' instead")>]
+        val of_vector  : Vector<'T>        -> Matrix<'T>
+        [<System.Obsolete("This function has been renamed. Use 'Matrix.Generic.toScalar' instead")>]
+        val to_scalar : Matrix<'T>         -> 'T                
+        [<System.Obsolete("This function has been renamed. Use 'Matrix.Generic.toRowVector' instead")>]
+        val to_rowvec : Matrix<'T>         -> RowVector<'T>                 
+        [<System.Obsolete("This function has been renamed. Use 'Matrix.Generic.toVector' instead")>]
+        val to_vector : Matrix<'T>         -> Vector<'T> 
+        [<Obsolete("This function has been renamed to 'initDiagonal'")>]
+        val init_diagonal : Vector<'T>        -> Matrix<'T>
+        [<Obsolete("This function has been renamed to 'initDense'")>]
+        val init_dense : int -> int -> seq<int * int * 'T>  -> Matrix<'T>
+        [<Obsolete("This function has been renamed to 'initSparse'")>]
+        val init_sparse : int -> int -> seq<int * int * 'T>  -> Matrix<'T>
+        [<Obsolete("Use the '.NonZeroEntries' property instead")>]
+        val nonzero_entries : Matrix<'T> -> seq<int * int * 'T> 
+        [<Obsolete("Use the 'Matrix.Generic.init' function instead")>]
+        val constDiag : int -> 'T          -> Matrix<'T>
+        [<Obsolete("Use the '+' operator instead")>]
+        val add       : Matrix<'T> -> Matrix<'T> -> Matrix<'T>
+        [<Obsolete("Use the 'initDiagonal' function instead")>]
+        val diag      : Vector<'T>        -> Matrix<'T>
+        [<Obsolete("Use the '*' operator instead")>]
+        val mul       : Matrix<'T> -> Matrix<'T> -> Matrix<'T>
+        [<Obsolete("Use the '*' operator instead")>]
+        val mulV      : Matrix<'T> -> Vector<'T> -> Vector<'T>
+        [<Obsolete("Use the '*' operator instead")>]
+        val mulRV     : RowVector<'T> -> Matrix<'T> -> RowVector<'T>
+        [<Obsolete("Use the '.*' operator instead")>]
+        val cptMul    : Matrix<'T> -> Matrix<'T> -> Matrix<'T>
+        [<Obsolete("Use the '-' operator instead")>]
+        val sub       : Matrix<'T> -> Matrix<'T> -> Matrix<'T>
+        [<Obsolete("Use the '-' prefix operator instead")>]
+        val neg       : Matrix<'T> -> Matrix<'T>
+        [<Obsolete("Use the '*' operator instead")>]
+        val scale     : 'T  -> Matrix<'T> -> Matrix<'T>
+        [<Obsolete("Use the '.Column' method instead")>]
+        val getCol  : Matrix<'T> -> int -> Vector<'T>
+        [<Obsolete("Use the '.Row' method instead")>]
+        val getRow  : Matrix<'T> -> int -> RowVector<'T>
+        [<Obsolete("Use the '.Columns' method instead")>]
+        val getCols : Matrix<'T> -> start:int -> length:int -> Matrix<'T>
+        [<Obsolete("Use the '.Rows' method instead")>]
+        val getRows : Matrix<'T> -> start:int -> length:int -> Matrix<'T>
+        [<Obsolete("Use the '.Region' method instead")>]
+        val getRegion  : Matrix<'T> -> starti:int -> startj:int -> lengthi:int -> lengthj:int -> Matrix<'T>
+        [<Obsolete("Use the '.Diagonal' method instead")>]
+        val getDiagN : Matrix<'T> -> int    -> Vector<'T>
+        [<Obsolete("Use the '.Diagonal' property instead")>]
+        val getDiag  : Matrix<'T>           -> Vector<'T>
+        [<Obsolete("This function will be removed in a future revision of this library. Just use 'compare m1 m2' instead")>]
+        val compare  : Matrix<'T> -> Matrix<'T> -> int
+        [<Obsolete("This function will be removed in a future revision of this library. Just use 'hash m' instead")>]
+        val hash     : Matrix<'T> -> int
+        [<Obsolete("This function will be removed in a future revision of this library. Set the elements of the matrix directly instead using 'm.[i,j] <- v'")>]
+        val inplace_assign       : (int -> int -> 'T) -> Matrix<'T> -> unit
+        [<Obsolete("This function will be removed in a future revision of this library. Set the elements of the matrix directly instead using 'm.[i,j] <- v'")>]
+        val inplace_mapi  : (int -> int -> 'T -> 'T) -> Matrix<'T> -> unit
+        [<Obsolete("This function will be removed in a future revision of this library. Set the elements of the matrix directly instead using 'm.[i,j] <- v'")>]
+        val inplace_cptMul : Matrix<'T> -> Matrix<'T> -> unit
+        [<Obsolete("This function will be removed in a future revision of this library. Set the elements of the matrix directly instead using 'm.[i,j] <- v'")>]
+        val inplace_scale  : 'T -> Matrix<'T> -> unit
+
+
+/// Operations to manipulate floating
+/// point column vectors. The submodule VectorOps.Generic contains a 
+/// matching set of operations to manipulate column vectors carrying
+/// arbitrary element types.
+[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+[<RequireQualifiedAccess>]
+module Vector =
+
+    /// Get an element of a column vector
+    val get   : vector -> int -> float
+
+    /// Set an element of a column vector
+    val set   : vector -> int -> float -> unit
+
+    /// Get the dimensions (number of rows) of a column vector. Identical to <c>nrows</c>
+    val length   : vector -> int 
+
+    /// Create a vector of a fixed length using a function to compute the initial element values
+    val init  : int ->        (int -> float)        -> vector
+
+    /// Create a vector from a list of numbers
+    val ofList   : float list          -> vector
+    
+    /// Create a vector from a sequence of numbers
+    val ofSeq    : seq<float>         -> vector
+
+    /// Create a vector from an array of double precision floats
+    val ofArray  : float array         -> vector
+
+    /// Return a new array containing a copy of the elements of the given vector
+    val toArray  : vector           -> float array
+    
+    /// Create a 1-element vector
+    val ofScalar  : float              -> vector
+
+    /// Generate a vector of the given length where each entry contains the given value
+    val create    : int        -> float -> vector
+    
+    /// Return a vector of the given length where every entry is zero.
+    val zero     : int                 -> vector
+    
+    /// Create a vector that represents a mesh over the given range
+    /// e.g. rangef (-1.0) 0.5 1.0 = vector [ -1.0; -0.5; 0.0; 0.5; 1.0]
+    val rangef : float -> float -> float -> vector
+    
+    /// Create a vector that represents a integral mesh over the given range
+    /// e.g. range 1 5 = vector [ 1.;2.;3.;4.;5. ]
+    val range  : int -> int              -> vector
+      
+    ///Dot product
+    val dot       : vector -> vector -> float
+
+    ///Point-wise exponential of a vector.
+    val cptPow    : vector -> float -> vector
+
+    ///Transpose of a matrix. Use also m.Transpose
+    val transpose     :           vector -> rowvec
+
+    ///Sum all the elements of a vector
+    val sum       : vector -> float
+
+    ///Multiply all the elements of a matrix
+    val prod      : vector -> float
+
+    /// Computes the 2-norm of a vector: sqrt(x.Transpose*x).
+    val norm      : vector -> float
+
+    /// Return true if a predicate returns true for all values in a vector
+    val forall  : (float -> bool) -> vector -> bool
+
+    /// Return true if a predicate returns true for some value in a vector
+    val exists  : (float -> bool) -> vector -> bool 
+
+    /// Return true if an indexed predicate returns true for all values in a vector
+    val foralli  : (int ->        float -> bool) -> vector -> bool
+
+    /// Return true if an indexed predicate returns true for some value in a vector
+    val existsi  : (int ->        float -> bool) -> vector -> bool 
+
+    /// Fold a function over all elements of a vector
+    val fold      : ('T -> float -> 'T) -> 'T         -> vector -> 'T
+
+    /// Fold an indexed function over all elements of a vector
+    val foldi      : (int -> 'T -> float -> 'T) -> 'T         -> vector -> 'T
+
+    /// Copy a vector
+    val copy : vector -> vector
+    
+    /// Map a function over each element of a vector
+    val map  : (float -> float) -> vector -> vector
+   
+    /// Map an indexed function over each element of a vector
+    val mapi  : (int        -> float -> float) -> vector -> vector
+   
+    [<System.Obsolete("This function has been renamed. Use 'Vector.ofList' instead")>]
+    val of_list   : float list          -> vector
+    [<System.Obsolete("This function has been renamed. Use 'Vector.ofSeq' instead")>]
+    val of_seq    : seq<float>         -> vector
+    [<System.Obsolete("This function has been renamed. Use 'Vector.ofArray' instead")>]
+    val of_array  : float array         -> vector
+    [<System.Obsolete("This function has been renamed. Use 'Vector.toArray' instead")>]
+    val to_array  : vector           -> float array
+    [<System.Obsolete("This function has been renamed. Use 'Vector.ofScalar' instead")>]
+    val of_scalar  : float              -> vector
+    [<Obsolete("Use the '+' operator instead")>]
+    val add       : vector -> vector -> vector
+    [<Obsolete("Use the '-' operator instead")>]
+    val sub       : vector -> vector -> vector
+    [<Obsolete("Use the '-' prefix operator instead")>]
+    val neg       :           vector -> vector
+    [<Obsolete("This function will be removed in a future revision of this library. Set the elements of the vector directly instead using 'vec.[i] <- x'")>]
+    val inplace_assign       : (int ->        float) -> vector -> unit
+    [<Obsolete("This function will be removed in a future revision of this library. Set the elements of the vector directly instead using 'vec.[i] <- x'")>]
+    val inplace_mapi  : (int ->        float -> float) -> vector -> unit
+    [<Obsolete("This function will be removed in a future revision of this library. Set the elements of the vector directly instead using 'vec.[i] <- x'")>]
+    val inplace_add    : vector -> vector -> unit
+    [<Obsolete("This function will be removed in a future revision of this library. Set the elements of the vector directly instead using 'vec.[i] <- x'")>]
+    val inplace_sub    : vector -> vector -> unit
+    [<Obsolete("This function will be removed in a future revision of this library. Set the elements of the vector directly instead using 'vec.[i] <- x'")>]
+    val inplace_cptMul : vector -> vector -> unit
+    [<Obsolete("This function will be removed in a future revision of this library. Set the elements of the vector directly instead using 'vec.[i] <- x'")>]
+    val inplace_scale  : float -> vector -> unit
+    [<Obsolete("Use the '.*' operator instead")>]
+    val cptMul    : vector -> vector -> vector
+    [<Obsolete("Use the '*' operator instead")>]
+    val scale     : float  -> vector -> vector
+
+    
+    /// Operations to manipulate column vectors carrying
+    /// arbitrary element types. 
+    module Generic =
+        // Accessors
+
+        /// Get an element of a column vector
+        val get   : Vector<'T> -> int -> 'T
+
+        /// Set an element of a column vector
+        val set   : Vector<'T> -> int -> 'T -> unit
+
+        /// Get the dimensions (number of rows) of a column vector. Identical to <c>nrows</c>
+        val length   : Vector<'T> -> int 
+
+        /// Creation: general
+        val init  : int ->        (int -> 'T)        -> Vector<'T>
+
+        /// Creation: useful when the element type has associated operations.
+        val initNumeric  : int ->        (INumeric<'T> -> int -> 'T)        -> Vector<'T>
+
+        /// Create a vector from a list of numbers
+        val ofList   : 'T list          -> Vector<'T>
+      
+        /// Create a vector from a sequence of numbers
+        val ofSeq    : seq<'T>         -> Vector<'T>
+
+        /// Create a 1-element vector
+        val ofScalar  : 'T              -> Vector<'T>
+
+        /// Create a vector from an array of elements
+        val ofArray  : 'T[]         -> Vector<'T>
+
+        /// Return a new array containing a copy of the elements of the given vector
+        val toArray  : Vector<'T>    -> 'T[]
+
+        /// Generate a vector of the given length where each entry contains the given value
+        val create    : int        -> 'T -> Vector<'T>
+      
+        /// Return a vector of the given length where every entry is zero.
+        val zero     : int                 -> Vector<'T>
+      
+        ///Take the pointwise maximum of two vectors
+        val cptMax    : Vector<'T> -> Vector<'T> -> Vector<'T> when 'T : comparison
+
+        ///Take the pointwise minimum of two vectors
+        val cptMin    : Vector<'T> -> Vector<'T> -> Vector<'T> when 'T : comparison
+
+        ///Dot product
+        val dot       : Vector<'T> -> Vector<'T> -> 'T
+
+        ///Sum all the elements of a vector
+        val sum       : Vector<'T> -> 'T
+      
+        ///Multiply all the elements of a matrix
+        val prod      : Vector<'T> -> 'T
+
+        /// Computes the 2-norm of a vector: sqrt(x.Transpose*x).
+        val norm      : Vector<'T> -> float
+
+        /// Return true if a predicate returns true for all values in a vector
+        val forall  : predicate:('T -> bool) -> Vector<'T> -> bool
+
+        /// Return true if a predicate returns true for some value in a vector
+        val exists  : predicate:('T -> bool) -> Vector<'T> -> bool 
+
+        /// Return true if an indexed predicate returns true for all values in a vector
+        val foralli  : (int -> 'T -> bool) -> Vector<'T> -> bool
+
+        /// Return true if an indexed predicate returns true for some value in a vector
+        val existsi  : (int -> 'T -> bool) -> Vector<'T> -> bool 
+
+        /// Fold a function over all elements of a vector
+        val fold      : folder:('State -> 'T -> 'State) -> 'State -> Vector<'T> -> 'State
+
+        /// Fold an indexed function over all elements of a vector
+        val foldi      : (int -> 'State -> 'T -> 'State) -> 'State -> Vector<'T> -> 'State
+
+        /// Copy the vector
+        val copy: Vector<'T> -> Vector<'T>
+        
+        /// Map a function over each element of a vector
+        val map  : ('T -> 'T) -> Vector<'T> -> Vector<'T>
+     
+        /// Map an indexed function over each element of a vector
+        val mapi  : (int        -> 'T -> 'T) -> Vector<'T> -> Vector<'T>
+     
+
+        [<System.Obsolete("This function has been renamed. Use 'Vector.ofList' instead")>]
+        val of_list   : 'T list          -> Vector<'T>
+        [<System.Obsolete("This function has been renamed. Use 'Vector.ofSeq' instead")>]
+        val of_seq    : seq<'T>         -> Vector<'T>
+        [<System.Obsolete("This function has been renamed. Use 'Vector.ofScalar' instead")>]
+        val of_scalar  : 'T              -> Vector<'T>
+        [<System.Obsolete("This function has been renamed. Use 'Vector.ofArray' instead")>]
+        val of_array  : 'T[]         -> Vector<'T>
+        [<System.Obsolete("This function has been renamed. Use 'Vector.toArray' instead")>]
+        val to_array  : Vector<'T>    -> 'T[]
+        [<Obsolete("Use the .* operator instead")>]
+        val cptMul    : Vector<'T> -> Vector<'T> -> Vector<'T>      
+        [<Obsolete("Use the 'vector.Transpose' property instead")>]
+        val transpose : Vector<'T> -> RowVector<'T>
+        [<Obsolete("Use the '+' operator instead")>]
+        val add       : Vector<'T> -> Vector<'T> -> Vector<'T>
+        [<Obsolete("Use the '-' operator instead")>]
+        val sub       : Vector<'T> -> Vector<'T> -> Vector<'T>
+        [<Obsolete("Use the '-' prefix operator instead")>]
+        val neg       : Vector<'T> -> Vector<'T>
+        [<Obsolete("Use the '*' operator instead")>]
+        val scale     : 'T  -> Vector<'T> -> Vector<'T>
+        [<Obsolete("This function will be removed in a future revision of this library. Set the elements of the vector directly instead using 'vec.[i] <- x'")>]
+        val inplace_assign : (int -> 'T) -> Vector<'T> -> unit
+        [<Obsolete("This function will be removed in a future revision of this library. Set the elements of the vector directly instead using 'vec.[i] <- x'")>]
+        val inplace_mapi  : (int -> 'T -> 'T) -> Vector<'T> -> unit
+        [<Obsolete("This function will be removed in a future revision of this library. Set the elements of the vector directly instead using 'vec.[i] <- x'")>]
+        val inplace_add    : Vector<'T> -> Vector<'T> -> unit
+        [<Obsolete("This function will be removed in a future revision of this library. Set the elements of the vector directly instead using 'vec.[i] <- x'")>]
+        val inplace_sub    : Vector<'T> -> Vector<'T> -> unit
+        [<Obsolete("This function will be removed in a future revision of this library. Set the elements of the vector directly instead using 'vec.[i] <- x'")>]
+        val inplace_cptMul : Vector<'T> -> Vector<'T> -> unit
+        [<Obsolete("This function will be removed in a future revision of this library. Set the elements of the vector directly instead using 'vec.[i] <- x'")>]
+        val inplace_scale  : 'T -> Vector<'T> -> unit
+
+
+
+/// Operations to manipulate floating
+/// point row vectors. These are included for completeness and are
+/// nearly always transposed to column vectors.
+[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+[<RequireQualifiedAccess>]
+module RowVector =
+
+    /// Get an element of a column vector
+    val get   : rowvec -> int -> float
+
+    /// Set an element of a column rowvec
+    val set   : rowvec -> int -> float -> unit
+
+    /// Get the dimensions (number of rows) of a column rowvec. 
+    val length   : rowvec -> int 
+
+    /// Create by constant initialization
+    val create : int -> float  -> rowvec
+
+    /// Create by comprehension
+    val init : int ->  (int -> float) -> rowvec
+
+    /// Return a vector of the given length where every entry is zero.
+    val zero     : int -> rowvec
+
+    // Transpose the row vector
+    val transpose : rowvec -> vector
+
+    // Copy the row vector
+    val copy : rowvec -> rowvec
+
+    /// Create a vector from a list of numbers
+    val ofList   : float list          -> rowvec
+
+    /// Create a vector from a sequence of numbers
+    val ofSeq    : seq<float>         -> rowvec
+
+    /// Create a vector from an array of double precision floats
+    val ofArray  : float array         -> rowvec
+
+    /// Return a new array containing a copy of the elements of the given vector
+    val toArray  : rowvec              -> float array
+    
+    [<System.Obsolete("This function has been renamed. Use 'RowVector.ofList' instead")>]
+    val of_list   : float list          -> rowvec
+    [<System.Obsolete("This function has been renamed. Use 'RowVector.ofSeq' instead")>]
+    val of_seq    : seq<float>         -> rowvec
+    [<System.Obsolete("This function has been renamed. Use 'RowVector.ofArray' instead")>]
+    val of_array  : float array         -> rowvec
+    [<System.Obsolete("This function has been renamed. Use 'RowVector.toArray' instead")>]
+    val to_array  : rowvec              -> float array
+    
+    
+    /// Operations to manipulate row vectors types carrying
+    /// arbitrary element types. 
+    module Generic =
+        // Accessors
+
+        /// Get an element from a column vector. 
+        val get   : RowVector<'T> -> int -> 'T
+        /// Set an element in a column vector. 
+        val set   : RowVector<'T> -> int -> 'T -> unit
+        /// Get the number of rows in a column vector. 
+        val length: RowVector<'T> -> int 
+        /// Transpose the row vector
+        val transpose        : RowVector<'T>  -> Vector<'T> 
+        /// Create by comprehension
+        val init       : int ->        (int -> 'T)        -> RowVector<'T> 
+        /// Create by constant initialization
+        val create       : int ->      'T  -> RowVector<'T> 
+        /// Return a vector of the given length where every entry is zero.
+        val zero     : int                 -> RowVector<'T>
+        /// Create a row vector from a list of elements
+        val ofList   : 'T list          -> RowVector<'T> 
+        /// Create a row vector from a sequence of elements
+        val ofSeq    : seq<'T>         -> RowVector<'T> 
+
+        /// Create a row vector from an array of elements
+        val ofArray  : 'T[]         -> RowVector<'T>
+
+        /// Return a new array containing a copy of the elements of the given vector
+        val toArray  : RowVector<'T>    -> 'T[]         
+
+        // Copy the row vector
+        val copy    :   RowVector<'T> -> RowVector<'T>
+
+        [<System.Obsolete("This function has been renamed. Use 'RowVector.Generic.ofList' instead")>]
+        val of_list   : 'T list          -> RowVector<'T> 
+        [<System.Obsolete("This function has been renamed. Use 'RowVector.Generic.ofSeq' instead")>]
+        val of_seq    : seq<'T>         -> RowVector<'T> 
+        [<System.Obsolete("This function has been renamed. Use 'RowVector.Generic.ofArray' instead")>]
+        val of_array  : 'T[]         -> RowVector<'T>
+        [<System.Obsolete("This function has been renamed. Use 'RowVector.Generic.toArray' instead")>]
+        val to_array  : RowVector<'T>    -> 'T[]         
+
+[<AutoOpen>]
+module MatrixTopLevelOperators = 
+    /// Builds a matrix from a sequence of sequence of floats.
+    val matrix : seq<#seq<float>> -> matrix
+    /// Builds a (column) vector from a sequence of floats.
+    val vector : seq<float> -> vector
+    /// Builds a (row) vector from a sequence of floats.
+    val rowvec : seq<float> -> rowvec
+
--- fsharp-3.1.1.26+dfsg2.orig/FSharp.PowerPack/math/q.fs
+++ fsharp-3.1.1.26+dfsg2/FSharp.PowerPack/math/q.fs
@@ -1,305 +1,305 @@
-// (c) Microsoft Corporation. All rights reserved 
-
-#nowarn "44"  // OK to use the "compiler only" function RangeGeneric
-#nowarn "52"  // The value has been copied to ensure the original is not mutated by this operation
-
-namespace Microsoft.FSharp.Math
-
-    open System
-    open System.Numerics
-    open System.Globalization
-
-    module BigRationalLargeImpl = 
-        let ZeroI = new BigInteger(0)
-        let OneI = new BigInteger(1)
-        let bigint (x:int) = new BigInteger(x)
-        let ToDoubleI (x:BigInteger) =  double x
-        let ToInt32I (x:BigInteger) = int32 x
-
-    open BigRationalLargeImpl
-        
-    [<CustomEquality; CustomComparison>]
-    type BigRationalLarge = 
-        | Q of BigInteger * BigInteger // invariants: (p,q) in lowest form, q >= 0 
-
-        override n.ToString() =
-            let (Q(p,q)) = n 
-            if q.IsOne then p.ToString() 
-            else p.ToString() + "/" + q.ToString()
-
-
-        static member Hash (Q(ap,aq)) = 
-            // This hash code must be identical to the hash for BigInteger when the numbers coincide.
-            if aq.IsOne then ap.GetHashCode() else (ap.GetHashCode() <<< 3) + aq.GetHashCode()
-        
-
-        override x.GetHashCode()            = BigRationalLarge.Hash(x)
-        
-        static member Equals(Q(ap,aq), Q(bp,bq)) = 
-            BigInteger.(=)  (ap,bp) && BigInteger.(=) (aq,bq)   // normal form, so structural equality 
-        
-        static member LessThan(Q(ap,aq), Q(bp,bq)) = 
-            BigInteger.(<)  (ap * bq,bp * aq)
-        
-        // note: performance improvement possible here
-        static member Compare(p,q) = 
-            if BigRationalLarge.LessThan(p,q) then -1 
-            elif BigRationalLarge.LessThan(q,p)then  1 
-            else 0 
-
-        interface System.IComparable with 
-            member this.CompareTo(obj:obj) = 
-                match obj with 
-                | :? BigRationalLarge as that -> BigRationalLarge.Compare(this,that)
-                | _ -> invalidArg "obj" "the object does not have the correct type"
-
-        override this.Equals(that:obj) = 
-            match that with 
-            | :? BigRationalLarge as that -> BigRationalLarge.Equals(this,that)
-            | _ -> false
-
-        member x.IsNegative = let (Q(ap,_)) = x in sign ap < 0
-        member x.IsPositive = let (Q(ap,_)) = x in sign ap > 0
-
-        member x.Numerator = let (Q(p,_)) = x in p
-        member x.Denominator = let (Q(_,q)) = x in q
-        member x.Sign = (let (Q(p,_)) = x in sign p)
-
-        static member ToDouble (Q(p,q)) = 
-            ToDoubleI p / ToDoubleI q
-
-        static member Normalize (p:BigInteger,q:BigInteger) =
-            if q.IsZero then
-                raise (System.DivideByZeroException())  (* throw for any x/0 *)
-            elif q.IsOne then
-                Q(p,q)
-            else
-                let k = BigInteger.GreatestCommonDivisor(p,q)
-                let p = p / k 
-                let q = q / k 
-                if sign q < 0 then Q(-p,-q) else Q(p,q)
-
-        static member Rational  (p:int,q:int) = BigRationalLarge.Normalize (bigint p,bigint q)
-        static member RationalZ (p,q) = BigRationalLarge.Normalize (p,q)
-       
-        static member Parse (str:string) =
-          let len = str.Length 
-          if len=0 then invalidArg "str" "empty string";
-          let j = str.IndexOf '/' 
-          if j >= 0 then 
-              let p = BigInteger.Parse (str.Substring(0,j)) 
-              let q = BigInteger.Parse (str.Substring(j+1,len-j-1)) 
-              BigRationalLarge.RationalZ (p,q)
-          else
-              let p = BigInteger.Parse str 
-              BigRationalLarge.RationalZ (p,OneI)
-        
-        static member (~-) (Q(bp,bq))    = Q(-bp,bq)          // still coprime, bq >= 0 
-        static member (+) (Q(ap,aq),Q(bp,bq)) = BigRationalLarge.Normalize ((ap * bq) + (bp * aq),aq * bq)
-        static member (-) (Q(ap,aq),Q(bp,bq)) = BigRationalLarge.Normalize ((ap * bq) - (bp * aq),aq * bq)
-        static member (*) (Q(ap,aq),Q(bp,bq)) = BigRationalLarge.Normalize (ap * bp,aq * bq)
-        static member (/) (Q(ap,aq),Q(bp,bq)) = BigRationalLarge.Normalize (ap * bq,aq * bp)
-        static member ( ~+ )(n1:BigRationalLarge) = n1
-        
- 
-    [<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
-    module BigRationalLarge = 
-        open System.Numerics
-    
-        let inv    (Q(ap,aq)) = BigRationalLarge.Normalize(aq,ap)    
-
-        let pown (Q(p,q)) (n:int) = Q(BigInteger.Pow(p,n),BigInteger.Pow  (q,n)) // p,q powers still coprime
-        
-        let equal (Q(ap,aq)) (Q(bp,bq)) = ap=bp && aq=bq   // normal form, so structural equality 
-        let lt    a b = BigRationalLarge.LessThan(a,b)
-        let gt    a b = BigRationalLarge.LessThan(b,a)
-        let lte   (Q(ap,aq)) (Q(bp,bq)) = BigInteger.(<=) (ap * bq,bp * aq)
-        let gte   (Q(ap,aq)) (Q(bp,bq)) = BigInteger.(>=) (ap * bq,bp * aq)
-
-        let of_bigint   z = BigRationalLarge.RationalZ(z,OneI )
-        let of_int n = BigRationalLarge.Rational(n,1)
-       
-        // integer part
-        let integer (Q(p,q)) =
-            let mutable r = BigInteger(0)
-            let d = BigInteger.DivRem (p,q,&r)          // have p = d.q + r, |r| < |q| 
-            if r < ZeroI
-            then d - OneI                 // p = (d-1).q + (r+q) 
-            else d                             // p =     d.q + r       
-      
-        
-    //----------------------------------------------------------------------------
-    // BigRational
-    //--------------------------------------------------------------------------
-
-    [<CustomEquality; CustomComparison>]
-    [<StructuredFormatDisplay("{StructuredDisplayString}N")>]
-    type BigRational =
-        | Z of BigInteger
-        | Q of BigRationalLarge
-
-        static member ( + )(n1,n2) = 
-            match n1,n2 with
-            | Z z ,Z zz -> Z (z + zz)
-            | Q q ,Q qq -> Q (q + qq)
-            | Z z ,Q qq -> Q (BigRationalLarge.of_bigint z + qq)
-            | Q q ,Z zz -> Q (q  + BigRationalLarge.of_bigint zz)
-
-        static member ( * )(n1,n2) = 
-            match n1,n2 with
-            | Z z ,Z zz -> Z (z * zz)
-            | Q q ,Q qq -> Q (q * qq)
-            | Z z ,Q qq -> Q (BigRationalLarge.of_bigint z * qq)
-            | Q q ,Z zz -> Q (q  * BigRationalLarge.of_bigint zz)
-
-        static member ( - )(n1,n2) = 
-            match n1,n2 with
-            | Z z ,Z zz -> Z (z - zz)
-            | Q q ,Q qq -> Q (q - qq)
-            | Z z ,Q qq -> Q (BigRationalLarge.of_bigint z - qq)
-            | Q q ,Z zz -> Q (q  - BigRationalLarge.of_bigint zz)
-
-        static member ( / )(n1,n2) = 
-            match n1,n2 with
-            | Z z ,Z zz -> Q (BigRationalLarge.RationalZ(z,zz))
-            | Q q ,Q qq -> Q (q / qq)
-            | Z z ,Q qq -> Q (BigRationalLarge.of_bigint z / qq)
-            | Q q ,Z zz -> Q (q  / BigRationalLarge.of_bigint zz)
-
-        static member ( ~- )(n1) = 
-            match n1 with
-            | Z z -> Z (-z)
-            | Q q -> Q (-q)
-
-        static member ( ~+ )(n1:BigRational) = n1
-
-        // nb. Q and Z hash codes must match up - see notes above
-        override n.GetHashCode() = 
-            match n with 
-            | Z z -> z.GetHashCode()
-            | Q q -> q.GetHashCode() 
-
-        override this.Equals(obj:obj) = 
-            match obj with 
-            | :? BigRational as that -> BigRational.(=)(this, that)
-            | _ -> false
-
-        interface System.IComparable with 
-            member n1.CompareTo(obj:obj) = 
-                match obj with 
-                | :? BigRational as n2 -> 
-                      if BigRational.(<)(n1, n2) then -1 elif BigRational.(=)(n1, n2) then 0 else 1
-                | _ -> invalidArg "obj" "the objects are not comparable"
-
-        static member FromInt (x:int) = Z (bigint x)
-        static member FromBigInt x = Z x
-
-        static member Zero = BigRational.FromInt(0) 
-        static member One = BigRational.FromInt(1) 
-
-
-        static member PowN (n,i:int) =
-            match n with
-            | Z z -> Z (BigInteger.Pow (z,i))
-            | Q q -> Q (BigRationalLarge.pown q i)
-
-        static member op_Equality (n,nn) = 
-            match n,nn with
-            | Z z ,Z zz -> BigInteger.(=) (z,zz)
-            | Q q ,Q qq -> (BigRationalLarge.equal q qq)
-            | Z z ,Q qq -> (BigRationalLarge.equal (BigRationalLarge.of_bigint z) qq)
-            | Q q ,Z zz -> (BigRationalLarge.equal q (BigRationalLarge.of_bigint zz))
-        static member op_Inequality (n,nn) = not (BigRational.op_Equality(n,nn))
-    
-        static member op_LessThan (n,nn) = 
-            match n,nn with
-            | Z z ,Z zz -> BigInteger.(<) (z,zz)
-            | Q q ,Q qq -> (BigRationalLarge.lt q qq)
-            | Z z ,Q qq -> (BigRationalLarge.lt (BigRationalLarge.of_bigint z) qq)
-            | Q q ,Z zz -> (BigRationalLarge.lt q (BigRationalLarge.of_bigint zz))
-        static member op_GreaterThan (n,nn) = 
-            match n,nn with
-            | Z z ,Z zz -> BigInteger.(>) (z,zz)
-            | Q q ,Q qq -> (BigRationalLarge.gt q qq)
-            | Z z ,Q qq -> (BigRationalLarge.gt (BigRationalLarge.of_bigint z) qq)
-            | Q q ,Z zz -> (BigRationalLarge.gt q (BigRationalLarge.of_bigint zz))
-        static member op_LessThanOrEqual (n,nn) = 
-            match n,nn with
-            | Z z ,Z zz -> BigInteger.(<=) (z,zz)
-            | Q q ,Q qq -> (BigRationalLarge.lte q qq)
-            | Z z ,Q qq -> (BigRationalLarge.lte (BigRationalLarge.of_bigint z) qq)
-            | Q q ,Z zz -> (BigRationalLarge.lte q (BigRationalLarge.of_bigint zz))
-        static member op_GreaterThanOrEqual (n,nn) = 
-            match n,nn with
-            | Z z ,Z zz -> BigInteger.(>=) (z,zz)
-            | Q q ,Q qq -> (BigRationalLarge.gte q qq)
-            | Z z ,Q qq -> (BigRationalLarge.gte (BigRationalLarge.of_bigint z) qq)
-            | Q q ,Z zz -> (BigRationalLarge.gte q (BigRationalLarge.of_bigint zz))
-        
-
-        member n.IsNegative = 
-            match n with 
-            | Z z -> sign z < 0 
-            | Q q -> q.IsNegative
-
-        member n.IsPositive = 
-            match n with 
-            | Z z -> sign z > 0
-            | Q q -> q.IsPositive
-            
-        member n.Numerator = 
-            match n with 
-            | Z z -> z
-            | Q q -> q.Numerator
-
-        member n.Denominator = 
-            match n with 
-            | Z _ -> OneI
-            | Q q -> q.Denominator
-
-        member n.Sign = 
-            if n.IsNegative then -1 
-            elif n.IsPositive then  1 
-            else 0
-
-        static member Abs(n:BigRational) = 
-            if n.IsNegative then -n else n
-
-        static member ToDouble(n:BigRational) = 
-            match n with
-            | Z z -> ToDoubleI z
-            | Q q -> BigRationalLarge.ToDouble q
-
-        static member ToBigInt(n:BigRational) = 
-            match n with 
-            | Z z -> z
-            | Q q -> BigRationalLarge.integer q 
-
-        static member ToInt32(n:BigRational) = 
-            match n with 
-            | Z z -> ToInt32I(z)
-            | Q q -> ToInt32I(BigRationalLarge.integer q )
-
-        static member op_Explicit (n:BigRational) = BigRational.ToInt32 n
-        static member op_Explicit (n:BigRational) = BigRational.ToDouble n
-        static member op_Explicit (n:BigRational) = BigRational.ToBigInt n
-
-
-        override n.ToString() = 
-            match n with 
-            | Z z -> z.ToString()
-            | Q q -> q.ToString()
-
-        member x.StructuredDisplayString = x.ToString()
-                   
-        static member Parse(s:string) = Q (BigRationalLarge.Parse s)
-
-    type BigNum = BigRational
-    type bignum = BigNum
-
-    module NumericLiteralN = 
-        let FromZero () = BigRational.Zero 
-        let FromOne () = BigRational.One 
-        let FromInt32 i = BigRational.FromInt i
-        let FromInt64 (i64:int64) = BigRational.FromBigInt (new BigInteger(i64))
-        let FromString s = BigRational.Parse s
+// (c) Microsoft Corporation. All rights reserved 
+
+#nowarn "44"  // OK to use the "compiler only" function RangeGeneric
+#nowarn "52"  // The value has been copied to ensure the original is not mutated by this operation
+
+namespace Microsoft.FSharp.Math
+
+    open System
+    open System.Numerics
+    open System.Globalization
+
+    module BigRationalLargeImpl = 
+        let ZeroI = new BigInteger(0)
+        let OneI = new BigInteger(1)
+        let bigint (x:int) = new BigInteger(x)
+        let ToDoubleI (x:BigInteger) =  double x
+        let ToInt32I (x:BigInteger) = int32 x
+
+    open BigRationalLargeImpl
+        
+    [<CustomEquality; CustomComparison>]
+    type BigRationalLarge = 
+        | Q of BigInteger * BigInteger // invariants: (p,q) in lowest form, q >= 0 
+
+        override n.ToString() =
+            let (Q(p,q)) = n 
+            if q.IsOne then p.ToString() 
+            else p.ToString() + "/" + q.ToString()
+
+
+        static member Hash (Q(ap,aq)) = 
+            // This hash code must be identical to the hash for BigInteger when the numbers coincide.
+            if aq.IsOne then ap.GetHashCode() else (ap.GetHashCode() <<< 3) + aq.GetHashCode()
+        
+
+        override x.GetHashCode()            = BigRationalLarge.Hash(x)
+        
+        static member Equals(Q(ap,aq), Q(bp,bq)) = 
+            BigInteger.(=)  (ap,bp) && BigInteger.(=) (aq,bq)   // normal form, so structural equality 
+        
+        static member LessThan(Q(ap,aq), Q(bp,bq)) = 
+            BigInteger.(<)  (ap * bq,bp * aq)
+        
+        // note: performance improvement possible here
+        static member Compare(p,q) = 
+            if BigRationalLarge.LessThan(p,q) then -1 
+            elif BigRationalLarge.LessThan(q,p)then  1 
+            else 0 
+
+        interface System.IComparable with 
+            member this.CompareTo(obj:obj) = 
+                match obj with 
+                | :? BigRationalLarge as that -> BigRationalLarge.Compare(this,that)
+                | _ -> invalidArg "obj" "the object does not have the correct type"
+
+        override this.Equals(that:obj) = 
+            match that with 
+            | :? BigRationalLarge as that -> BigRationalLarge.Equals(this,that)
+            | _ -> false
+
+        member x.IsNegative = let (Q(ap,_)) = x in sign ap < 0
+        member x.IsPositive = let (Q(ap,_)) = x in sign ap > 0
+
+        member x.Numerator = let (Q(p,_)) = x in p
+        member x.Denominator = let (Q(_,q)) = x in q
+        member x.Sign = (let (Q(p,_)) = x in sign p)
+
+        static member ToDouble (Q(p,q)) = 
+            ToDoubleI p / ToDoubleI q
+
+        static member Normalize (p:BigInteger,q:BigInteger) =
+            if q.IsZero then
+                raise (System.DivideByZeroException())  (* throw for any x/0 *)
+            elif q.IsOne then
+                Q(p,q)
+            else
+                let k = BigInteger.GreatestCommonDivisor(p,q)
+                let p = p / k 
+                let q = q / k 
+                if sign q < 0 then Q(-p,-q) else Q(p,q)
+
+        static member Rational  (p:int,q:int) = BigRationalLarge.Normalize (bigint p,bigint q)
+        static member RationalZ (p,q) = BigRationalLarge.Normalize (p,q)
+       
+        static member Parse (str:string) =
+          let len = str.Length 
+          if len=0 then invalidArg "str" "empty string";
+          let j = str.IndexOf '/' 
+          if j >= 0 then 
+              let p = BigInteger.Parse (str.Substring(0,j)) 
+              let q = BigInteger.Parse (str.Substring(j+1,len-j-1)) 
+              BigRationalLarge.RationalZ (p,q)
+          else
+              let p = BigInteger.Parse str 
+              BigRationalLarge.RationalZ (p,OneI)
+        
+        static member (~-) (Q(bp,bq))    = Q(-bp,bq)          // still coprime, bq >= 0 
+        static member (+) (Q(ap,aq),Q(bp,bq)) = BigRationalLarge.Normalize ((ap * bq) + (bp * aq),aq * bq)
+        static member (-) (Q(ap,aq),Q(bp,bq)) = BigRationalLarge.Normalize ((ap * bq) - (bp * aq),aq * bq)
+        static member (*) (Q(ap,aq),Q(bp,bq)) = BigRationalLarge.Normalize (ap * bp,aq * bq)
+        static member (/) (Q(ap,aq),Q(bp,bq)) = BigRationalLarge.Normalize (ap * bq,aq * bp)
+        static member ( ~+ )(n1:BigRationalLarge) = n1
+        
+ 
+    [<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
+    module BigRationalLarge = 
+        open System.Numerics
+    
+        let inv    (Q(ap,aq)) = BigRationalLarge.Normalize(aq,ap)    
+
+        let pown (Q(p,q)) (n:int) = Q(BigInteger.Pow(p,n),BigInteger.Pow  (q,n)) // p,q powers still coprime
+        
+        let equal (Q(ap,aq)) (Q(bp,bq)) = ap=bp && aq=bq   // normal form, so structural equality 
+        let lt    a b = BigRationalLarge.LessThan(a,b)
+        let gt    a b = BigRationalLarge.LessThan(b,a)
+        let lte   (Q(ap,aq)) (Q(bp,bq)) = BigInteger.(<=) (ap * bq,bp * aq)
+        let gte   (Q(ap,aq)) (Q(bp,bq)) = BigInteger.(>=) (ap * bq,bp * aq)
+
+        let of_bigint   z = BigRationalLarge.RationalZ(z,OneI )
+        let of_int n = BigRationalLarge.Rational(n,1)
+       
+        // integer part
+        let integer (Q(p,q)) =
+            let mutable r = BigInteger(0)
+            let d = BigInteger.DivRem (p,q,&r)          // have p = d.q + r, |r| < |q| 
+            if r < ZeroI
+            then d - OneI                 // p = (d-1).q + (r+q) 
+            else d                             // p =     d.q + r       
+      
+        
+    //----------------------------------------------------------------------------
+    // BigRational
+    //--------------------------------------------------------------------------
+
+    [<CustomEquality; CustomComparison>]
+    [<StructuredFormatDisplay("{StructuredDisplayString}N")>]
+    type BigRational =
+        | Z of BigInteger
+        | Q of BigRationalLarge
+
+        static member ( + )(n1,n2) = 
+            match n1,n2 with
+            | Z z ,Z zz -> Z (z + zz)
+            | Q q ,Q qq -> Q (q + qq)
+            | Z z ,Q qq -> Q (BigRationalLarge.of_bigint z + qq)
+            | Q q ,Z zz -> Q (q  + BigRationalLarge.of_bigint zz)
+
+        static member ( * )(n1,n2) = 
+            match n1,n2 with
+            | Z z ,Z zz -> Z (z * zz)
+            | Q q ,Q qq -> Q (q * qq)
+            | Z z ,Q qq -> Q (BigRationalLarge.of_bigint z * qq)
+            | Q q ,Z zz -> Q (q  * BigRationalLarge.of_bigint zz)
+
+        static member ( - )(n1,n2) = 
+            match n1,n2 with
+            | Z z ,Z zz -> Z (z - zz)
+            | Q q ,Q qq -> Q (q - qq)
+            | Z z ,Q qq -> Q (BigRationalLarge.of_bigint z - qq)
+            | Q q ,Z zz -> Q (q  - BigRationalLarge.of_bigint zz)
+
+        static member ( / )(n1,n2) = 
+            match n1,n2 with
+            | Z z ,Z zz -> Q (BigRationalLarge.RationalZ(z,zz))
+            | Q q ,Q qq -> Q (q / qq)
+            | Z z ,Q qq -> Q (BigRationalLarge.of_bigint z / qq)
+            | Q q ,Z zz -> Q (q  / BigRationalLarge.of_bigint zz)
+
+        static member ( ~- )(n1) = 
+            match n1 with
+            | Z z -> Z (-z)
+            | Q q -> Q (-q)
+
+        static member ( ~+ )(n1:BigRational) = n1
+
+        // nb. Q and Z hash codes must match up - see notes above
+        override n.GetHashCode() = 
+            match n with 
+            | Z z -> z.GetHashCode()
+            | Q q -> q.GetHashCode() 
+
+        override this.Equals(obj:obj) = 
+            match obj with 
+            | :? BigRational as that -> BigRational.(=)(this, that)
+            | _ -> false
+
+        interface System.IComparable with 
+            member n1.CompareTo(obj:obj) = 
+                match obj with 
+                | :? BigRational as n2 -> 
+                      if BigRational.(<)(n1, n2) then -1 elif BigRational.(=)(n1, n2) then 0 else 1
+                | _ -> invalidArg "obj" "the objects are not comparable"
+
+        static member FromInt (x:int) = Z (bigint x)
+        static member FromBigInt x = Z x
+
+        static member Zero = BigRational.FromInt(0) 
+        static member One = BigRational.FromInt(1) 
+
+
+        static member PowN (n,i:int) =
+            match n with
+            | Z z -> Z (BigInteger.Pow (z,i))
+            | Q q -> Q (BigRationalLarge.pown q i)
+
+        static member op_Equality (n,nn) = 
+            match n,nn with
+            | Z z ,Z zz -> BigInteger.(=) (z,zz)
+            | Q q ,Q qq -> (BigRationalLarge.equal q qq)
+            | Z z ,Q qq -> (BigRationalLarge.equal (BigRationalLarge.of_bigint z) qq)
+            | Q q ,Z zz -> (BigRationalLarge.equal q (BigRationalLarge.of_bigint zz))
+        static member op_Inequality (n,nn) = not (BigRational.op_Equality(n,nn))
+    
+        static member op_LessThan (n,nn) = 
+            match n,nn with
+            | Z z ,Z zz -> BigInteger.(<) (z,zz)
+            | Q q ,Q qq -> (BigRationalLarge.lt q qq)
+            | Z z ,Q qq -> (BigRationalLarge.lt (BigRationalLarge.of_bigint z) qq)
+            | Q q ,Z zz -> (BigRationalLarge.lt q (BigRationalLarge.of_bigint zz))
+        static member op_GreaterThan (n,nn) = 
+            match n,nn with
+            | Z z ,Z zz -> BigInteger.(>) (z,zz)
+            | Q q ,Q qq -> (BigRationalLarge.gt q qq)
+            | Z z ,Q qq -> (BigRationalLarge.gt (BigRationalLarge.of_bigint z) qq)
+            | Q q ,Z zz -> (BigRationalLarge.gt q (BigRationalLarge.of_bigint zz))
+        static member op_LessThanOrEqual (n,nn) = 
+            match n,nn with
+            | Z z ,Z zz -> BigInteger.(<=) (z,zz)
+            | Q q ,Q qq -> (BigRationalLarge.lte q qq)
+            | Z z ,Q qq -> (BigRationalLarge.lte (BigRationalLarge.of_bigint z) qq)
+            | Q q ,Z zz -> (BigRationalLarge.lte q (BigRationalLarge.of_bigint zz))
+        static member op_GreaterThanOrEqual (n,nn) = 
+            match n,nn with
+            | Z z ,Z zz -> BigInteger.(>=) (z,zz)
+            | Q q ,Q qq -> (BigRationalLarge.gte q qq)
+            | Z z ,Q qq -> (BigRationalLarge.gte (BigRationalLarge.of_bigint z) qq)
+            | Q q ,Z zz -> (BigRationalLarge.gte q (BigRationalLarge.of_bigint zz))
+        
+
+        member n.IsNegative = 
+            match n with 
+            | Z z -> sign z < 0 
+            | Q q -> q.IsNegative
+
+        member n.IsPositive = 
+            match n with 
+            | Z z -> sign z > 0
+            | Q q -> q.IsPositive
+            
+        member n.Numerator = 
+            match n with 
+            | Z z -> z
+            | Q q -> q.Numerator
+
+        member n.Denominator = 
+            match n with 
+            | Z _ -> OneI
+            | Q q -> q.Denominator
+
+        member n.Sign = 
+            if n.IsNegative then -1 
+            elif n.IsPositive then  1 
+            else 0
+
+        static member Abs(n:BigRational) = 
+            if n.IsNegative then -n else n
+
+        static member ToDouble(n:BigRational) = 
+            match n with
+            | Z z -> ToDoubleI z
+            | Q q -> BigRationalLarge.ToDouble q
+
+        static member ToBigInt(n:BigRational) = 
+            match n with 
+            | Z z -> z
+            | Q q -> BigRationalLarge.integer q 
+
+        static member ToInt32(n:BigRational) = 
+            match n with 
+            | Z z -> ToInt32I(z)
+            | Q q -> ToInt32I(BigRationalLarge.integer q )
+
+        static member op_Explicit (n:BigRational) = BigRational.ToInt32 n
+        static member op_Explicit (n:BigRational) = BigRational.ToDouble n
+        static member op_Explicit (n:BigRational) = BigRational.ToBigInt n
+
+
+        override n.ToString() = 
+            match n with 
+            | Z z -> z.ToString()
+            | Q q -> q.ToString()
+
+        member x.StructuredDisplayString = x.ToString()
+                   
+        static member Parse(s:string) = Q (BigRationalLarge.Parse s)
+
+    type BigNum = BigRational
+    type bignum = BigNum
+
+    module NumericLiteralN = 
+        let FromZero () = BigRational.Zero 
+        let FromOne () = BigRational.One 
+        let FromInt32 i = BigRational.FromInt i
+        let FromInt64 (i64:int64) = BigRational.FromBigInt (new BigInteger(i64))
+        let FromString s = BigRational.Parse s
--- fsharp-3.1.1.26+dfsg2.orig/FSharp.PowerPack/math/q.fsi
+++ fsharp-3.1.1.26+dfsg2/FSharp.PowerPack/math/q.fsi
@@ -1,92 +1,92 @@
-// (c) Microsoft Corporation 2005-2009. 
-
-namespace Microsoft.FSharp.Math
-
-    open System
-    open System.Numerics
-      
-    /// The type of arbitrary-sized rational numbers
-    [<Sealed>]
-    type BigRational =
-        /// Return the sum of two rational numbers
-        static member ( + ) : BigRational * BigRational -> BigRational
-        /// Return the product of two rational numbers
-        static member ( * ) : BigRational * BigRational -> BigRational
-        /// Return the difference of two rational numbers
-        static member ( - ) : BigRational * BigRational -> BigRational
-        /// Return the ratio of two rational numbers
-        static member ( / ) : BigRational * BigRational -> BigRational
-        /// Return the negation of a rational number
-        static member ( ~- ): BigRational          -> BigRational
-        /// Return the given rational number
-        static member ( ~+ ): BigRational          -> BigRational
-
-        override ToString: unit -> string
-        override GetHashCode: unit -> int
-        interface System.IComparable
-
-        /// Get zero as a rational number
-        static member Zero : BigRational  
-        /// Get one as a rational number
-        static member One : BigRational  
-        /// This operator is for use from other .NET languages
-        static member op_Equality : BigRational * BigRational -> bool
-        /// This operator is for use from other .NET languages
-        static member op_Inequality : BigRational * BigRational -> bool
-        /// This operator is for use from other .NET languages
-        static member op_LessThan: BigRational * BigRational -> bool 
-        /// This operator is for use from other .NET languages
-        static member op_GreaterThan: BigRational * BigRational -> bool 
-        /// This operator is for use from other .NET languages
-        static member op_LessThanOrEqual: BigRational * BigRational -> bool 
-        /// This operator is for use from other .NET languages
-        static member op_GreaterThanOrEqual: BigRational * BigRational -> bool
-        
-        /// Return a boolean indicating if this rational number is strictly negative
-        member IsNegative: bool 
-        /// Return a boolean indicating if this rational number is strictly positive
-        member IsPositive: bool 
-
-        /// Return the numerator of the normalized rational number
-        member Numerator: BigInteger
-        /// Return the denominator of the normalized rational number
-        member Denominator: BigInteger
-
-        member StructuredDisplayString : string
-
-        /// Return the absolute value of a rational number 
-        static member Abs : BigRational -> BigRational
-        /// Return the sign of a rational number; 0, +1 or -1
-        member Sign : int 
-        /// Return the result of raising the given rational number to the given power
-        static member PowN : BigRational * int -> BigRational
-        /// Return the result of converting the given integer to a rational number
-        static member FromInt : int         -> BigRational  
-        /// Return the result of converting the given big integer to a rational number
-        static member FromBigInt : BigInteger      -> BigRational  
-        /// Return the result of converting the given rational number to a floating point number
-        static member ToDouble: BigRational -> float 
-        /// Return the result of converting the given rational number to a big integer
-        static member ToBigInt: BigRational -> BigInteger
-        /// Return the result of converting the given rational number to an integer
-        static member ToInt32 : BigRational -> int
-        /// Return the result of converting the given rational number to a floating point number
-        static member op_Explicit : BigRational -> float 
-        /// Return the result of converting the given rational number to a big integer
-        static member op_Explicit : BigRational -> BigInteger
-        /// Return the result of converting the given rational number to an integer
-        static member op_Explicit : BigRational -> int
-        /// Return the result of converting the string to a rational number 
-        static member Parse: string -> BigRational
-
-    type BigNum = BigRational
-
-    type bignum = BigRational
-
-    [<RequireQualifiedAccess>]
-    module NumericLiteralN = 
-        val FromZero : unit -> BigRational
-        val FromOne : unit -> BigRational
-        val FromInt32 : int32 -> BigRational
-        val FromInt64 : int64 -> BigRational
+// (c) Microsoft Corporation 2005-2009. 
+
+namespace Microsoft.FSharp.Math
+
+    open System
+    open System.Numerics
+      
+    /// The type of arbitrary-sized rational numbers
+    [<Sealed>]
+    type BigRational =
+        /// Return the sum of two rational numbers
+        static member ( + ) : BigRational * BigRational -> BigRational
+        /// Return the product of two rational numbers
+        static member ( * ) : BigRational * BigRational -> BigRational
+        /// Return the difference of two rational numbers
+        static member ( - ) : BigRational * BigRational -> BigRational
+        /// Return the ratio of two rational numbers
+        static member ( / ) : BigRational * BigRational -> BigRational
+        /// Return the negation of a rational number
+        static member ( ~- ): BigRational          -> BigRational
+        /// Return the given rational number
+        static member ( ~+ ): BigRational          -> BigRational
+
+        override ToString: unit -> string
+        override GetHashCode: unit -> int
+        interface System.IComparable
+
+        /// Get zero as a rational number
+        static member Zero : BigRational  
+        /// Get one as a rational number
+        static member One : BigRational  
+        /// This operator is for use from other .NET languages
+        static member op_Equality : BigRational * BigRational -> bool
+        /// This operator is for use from other .NET languages
+        static member op_Inequality : BigRational * BigRational -> bool
+        /// This operator is for use from other .NET languages
+        static member op_LessThan: BigRational * BigRational -> bool 
+        /// This operator is for use from other .NET languages
+        static member op_GreaterThan: BigRational * BigRational -> bool 
+        /// This operator is for use from other .NET languages
+        static member op_LessThanOrEqual: BigRational * BigRational -> bool 
+        /// This operator is for use from other .NET languages
+        static member op_GreaterThanOrEqual: BigRational * BigRational -> bool
+        
+        /// Return a boolean indicating if this rational number is strictly negative
+        member IsNegative: bool 
+        /// Return a boolean indicating if this rational number is strictly positive
+        member IsPositive: bool 
+
+        /// Return the numerator of the normalized rational number
+        member Numerator: BigInteger
+        /// Return the denominator of the normalized rational number
+        member Denominator: BigInteger
+
+        member StructuredDisplayString : string
+
+        /// Return the absolute value of a rational number 
+        static member Abs : BigRational -> BigRational
+        /// Return the sign of a rational number; 0, +1 or -1
+        member Sign : int 
+        /// Return the result of raising the given rational number to the given power
+        static member PowN : BigRational * int -> BigRational
+        /// Return the result of converting the given integer to a rational number
+        static member FromInt : int         -> BigRational  
+        /// Return the result of converting the given big integer to a rational number
+        static member FromBigInt : BigInteger      -> BigRational  
+        /// Return the result of converting the given rational number to a floating point number
+        static member ToDouble: BigRational -> float 
+        /// Return the result of converting the given rational number to a big integer
+        static member ToBigInt: BigRational -> BigInteger
+        /// Return the result of converting the given rational number to an integer
+        static member ToInt32 : BigRational -> int
+        /// Return the result of converting the given rational number to a floating point number
+        static member op_Explicit : BigRational -> float 
+        /// Return the result of converting the given rational number to a big integer
+        static member op_Explicit : BigRational -> BigInteger
+        /// Return the result of converting the given rational number to an integer
+        static member op_Explicit : BigRational -> int
+        /// Return the result of converting the string to a rational number 
+        static member Parse: string -> BigRational
+
+    type BigNum = BigRational
+
+    type bignum = BigRational
+
+    [<RequireQualifiedAccess>]
+    module NumericLiteralN = 
+        val FromZero : unit -> BigRational
+        val FromOne : unit -> BigRational
+        val FromInt32 : int32 -> BigRational
+        val FromInt64 : int64 -> BigRational
         val FromString : string -> BigRational
\ No newline at end of file
--- fsharp-3.1.1.26+dfsg2.orig/FSharp.SRGen.Build.Tasks/FSharp.SRGen.targets
+++ fsharp-3.1.1.26+dfsg2/FSharp.SRGen.Build.Tasks/FSharp.SRGen.targets
@@ -1,65 +1,65 @@
-<!--
-***********************************************************************************************
-FSharp.SRGen.targets
-
-WARNING:  DO NOT MODIFY this file unless you are knowledgeable about MSBuild and have
-		  created a backup copy.  Incorrect changes to this file will make it
-		  impossible to load or build your projects from the command-line or the IDE.
-
-Copyright (C) Microsoft Corporation. All rights reserved.
-***********************************************************************************************
--->
-
-<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <UsingTask TaskName="FsSrGen" AssemblyFile="FSharp.SRGen.Build.Tasks.dll"/>
-  <PropertyGroup>
-    <PrepareForBuildDependsOn>ProcessFsSrGen;$(PrepareForBuildDependsOn)</PrepareForBuildDependsOn>
-  </PropertyGroup>
-
-  <!-- Build FsSrGen files. -->
-  <Target
-		Name="CallFsSrGen"
-		Inputs="@(FsSrGen)"
-		Outputs="@(FsSrGen->'$(IntermediateOutputPath)%(Filename).fs');@(FsSrGen->'$(IntermediateOutputPath)%(Filename).resx')"
-		Condition="'@(FsSrGen)'!=''">
-    <!-- Create the output directory in case it doesn't exist yet -->
-    <MakeDir Directories="$(IntermediateOutputPath)"/>
-    <!-- Run the tool -->
-    <FsSrGen
-      InputFile="%(FsSrGen.FullPath)"
-      ToolPath="$(FsSrGenToolPath)"
-      OutputFsFile="$(IntermediateOutputPath)%(FsSrGen.Filename).fs"
-      OutputResxFile="$(IntermediateOutputPath)%(FsSrGen.Filename).resx"
-      >
-    </FsSrGen>
-  </Target>
-
-  <!-- Process FsSrGen rules. No 'Inputs' and 'Outputs' means this rule always runs if there is any @FsSrGen, even if up-to-date. -->
-  <Target
-		Name="ProcessFsSrGen"
-                DependsOnTargets="CallFsSrGen"
-		Condition="'@(FsSrGen)'!=''">
-    <!-- Make the outputs magically part of the project -->
-    <CreateItem Include="$(IntermediateOutputPath)%(FsSrGen.Filename).fs">
-      <Output TaskParameter="Include" ItemName="CompileBefore"/>
-    </CreateItem>
-    <CreateItem Include="$(IntermediateOutputPath)%(FsSrGen.Filename).resx"
-                AdditionalMetadata="ManifestResourceName=%(FsSrGen.Filename)">
-      <!-- Note AdditionalMetadata above; we need the name in the manifest to be Foo.resources and not e.g. obj.Debug.Foo.resources -->
-      <Output TaskParameter="Include" ItemName="EmbeddedResource"/>
-    </CreateItem>
-    <!-- Add them to the list of things under the IntermediateOutputPath that should be 'clean'ed -->
-    <CreateItem Include="$(IntermediateOutputPath)%(FsSrGen.Filename).fs">
-      <Output TaskParameter="Include" ItemName="FileWrites"/>
-    </CreateItem>
-    <CreateItem Include="$(IntermediateOutputPath)%(FsSrGen.Filename).resx">
-      <Output TaskParameter="Include" ItemName="FileWrites"/>
-    </CreateItem>
-  </Target>
-
-  <ItemGroup>
-    <AvailableItemName Include="FsSrGen">
-      <Visible>false</Visible>
-    </AvailableItemName>
-  </ItemGroup>
+<!--
+***********************************************************************************************
+FSharp.SRGen.targets
+
+WARNING:  DO NOT MODIFY this file unless you are knowledgeable about MSBuild and have
+		  created a backup copy.  Incorrect changes to this file will make it
+		  impossible to load or build your projects from the command-line or the IDE.
+
+Copyright (C) Microsoft Corporation. All rights reserved.
+***********************************************************************************************
+-->
+
+<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <UsingTask TaskName="FsSrGen" AssemblyFile="FSharp.SRGen.Build.Tasks.dll"/>
+  <PropertyGroup>
+    <PrepareForBuildDependsOn>ProcessFsSrGen;$(PrepareForBuildDependsOn)</PrepareForBuildDependsOn>
+  </PropertyGroup>
+
+  <!-- Build FsSrGen files. -->
+  <Target
+		Name="CallFsSrGen"
+		Inputs="@(FsSrGen)"
+		Outputs="@(FsSrGen->'$(IntermediateOutputPath)%(Filename).fs');@(FsSrGen->'$(IntermediateOutputPath)%(Filename).resx')"
+		Condition="'@(FsSrGen)'!=''">
+    <!-- Create the output directory in case it doesn't exist yet -->
+    <MakeDir Directories="$(IntermediateOutputPath)"/>
+    <!-- Run the tool -->
+    <FsSrGen
+      InputFile="%(FsSrGen.FullPath)"
+      ToolPath="$(FsSrGenToolPath)"
+      OutputFsFile="$(IntermediateOutputPath)%(FsSrGen.Filename).fs"
+      OutputResxFile="$(IntermediateOutputPath)%(FsSrGen.Filename).resx"
+      >
+    </FsSrGen>
+  </Target>
+
+  <!-- Process FsSrGen rules. No 'Inputs' and 'Outputs' means this rule always runs if there is any @FsSrGen, even if up-to-date. -->
+  <Target
+		Name="ProcessFsSrGen"
+                DependsOnTargets="CallFsSrGen"
+		Condition="'@(FsSrGen)'!=''">
+    <!-- Make the outputs magically part of the project -->
+    <CreateItem Include="$(IntermediateOutputPath)%(FsSrGen.Filename).fs">
+      <Output TaskParameter="Include" ItemName="CompileBefore"/>
+    </CreateItem>
+    <CreateItem Include="$(IntermediateOutputPath)%(FsSrGen.Filename).resx"
+                AdditionalMetadata="ManifestResourceName=%(FsSrGen.Filename)">
+      <!-- Note AdditionalMetadata above; we need the name in the manifest to be Foo.resources and not e.g. obj.Debug.Foo.resources -->
+      <Output TaskParameter="Include" ItemName="EmbeddedResource"/>
+    </CreateItem>
+    <!-- Add them to the list of things under the IntermediateOutputPath that should be 'clean'ed -->
+    <CreateItem Include="$(IntermediateOutputPath)%(FsSrGen.Filename).fs">
+      <Output TaskParameter="Include" ItemName="FileWrites"/>
+    </CreateItem>
+    <CreateItem Include="$(IntermediateOutputPath)%(FsSrGen.Filename).resx">
+      <Output TaskParameter="Include" ItemName="FileWrites"/>
+    </CreateItem>
+  </Target>
+
+  <ItemGroup>
+    <AvailableItemName Include="FsSrGen">
+      <Visible>false</Visible>
+    </AvailableItemName>
+  </ItemGroup>
 </Project>
\ No newline at end of file
--- fsharp-3.1.1.26+dfsg2.orig/FSharp.SRGen.Build.Tasks/FsSrGen.fs
+++ fsharp-3.1.1.26+dfsg2/FSharp.SRGen.Build.Tasks/FsSrGen.fs
@@ -1,46 +1,46 @@
-
-namespace Microsoft.FSharp.Build
-
-open System
-open Microsoft.Build.Framework
-open Microsoft.Build.Utilities
-
-type FsSrGen() =
-    inherit ToolTask()
-    let mutable inputFile  : string = null
-    let mutable toolPath : string = null
-    let mutable outputFsFile : string = null
-    let mutable outputResxFile : string = null
-    [<Required>]
-    member this.InputFile
-        with get ()  = inputFile
-        and  set (s) = inputFile <- s
-    [<Required>]
-    [<Output>]
-    member this.OutputFsFile
-        with get ()  = outputFsFile
-        and  set (s) = outputFsFile <- s
-    [<Required>]
-    [<Output>]
-    member this.OutputResxFile
-        with get ()  = outputResxFile
-        and  set (s) = outputResxFile <- s
-
-    // For targeting other versions
-    member this.ToolPath
-        with get ()  = toolPath
-        and  set (s) = toolPath <- s
-        
-    // ToolTask methods
-    override this.ToolName = "fssrgen.exe"
-
-    override this.GenerateFullPathToTool() =
-        System.IO.Path.Combine(toolPath, this.ToolExe)
-
-    override this.GenerateCommandLineCommands() =
-        let builder = new CommandLineBuilder()
-        builder.AppendSwitchIfNotNull(" ", inputFile)
-        builder.AppendSwitchIfNotNull(" ", outputFsFile)
-        builder.AppendSwitchIfNotNull(" ", outputResxFile)
-        let args = builder.ToString()
-        args
+
+namespace Microsoft.FSharp.Build
+
+open System
+open Microsoft.Build.Framework
+open Microsoft.Build.Utilities
+
+type FsSrGen() =
+    inherit ToolTask()
+    let mutable inputFile  : string = null
+    let mutable toolPath : string = null
+    let mutable outputFsFile : string = null
+    let mutable outputResxFile : string = null
+    [<Required>]
+    member this.InputFile
+        with get ()  = inputFile
+        and  set (s) = inputFile <- s
+    [<Required>]
+    [<Output>]
+    member this.OutputFsFile
+        with get ()  = outputFsFile
+        and  set (s) = outputFsFile <- s
+    [<Required>]
+    [<Output>]
+    member this.OutputResxFile
+        with get ()  = outputResxFile
+        and  set (s) = outputResxFile <- s
+
+    // For targeting other versions
+    member this.ToolPath
+        with get ()  = toolPath
+        and  set (s) = toolPath <- s
+        
+    // ToolTask methods
+    override this.ToolName = "fssrgen.exe"
+
+    override this.GenerateFullPathToTool() =
+        System.IO.Path.Combine(toolPath, this.ToolExe)
+
+    override this.GenerateCommandLineCommands() =
+        let builder = new CommandLineBuilder()
+        builder.AppendSwitchIfNotNull(" ", inputFile)
+        builder.AppendSwitchIfNotNull(" ", outputFsFile)
+        builder.AppendSwitchIfNotNull(" ", outputResxFile)
+        let args = builder.ToString()
+        args
--- fsharp-3.1.1.26+dfsg2.orig/FsLex/FsLex.fsproj.vspscc
+++ fsharp-3.1.1.26+dfsg2/FsLex/FsLex.fsproj.vspscc
@@ -1,10 +1,10 @@
-﻿""
-{
-"FILE_VERSION" = "9237"
-"ENLISTMENT_CHOICE" = "NEVER"
-"PROJECT_FILE_RELATIVE_PATH" = ""
-"NUMBER_OF_EXCLUDED_FILES" = "0"
-"ORIGINAL_PROJECT_FILE_PATH" = ""
-"NUMBER_OF_NESTED_PROJECTS" = "0"
-"SOURCE_CONTROL_SETTINGS_PROVIDER" = "PROVIDER"
-}
+﻿""
+{
+"FILE_VERSION" = "9237"
+"ENLISTMENT_CHOICE" = "NEVER"
+"PROJECT_FILE_RELATIVE_PATH" = ""
+"NUMBER_OF_EXCLUDED_FILES" = "0"
+"ORIGINAL_PROJECT_FILE_PATH" = ""
+"NUMBER_OF_NESTED_PROJECTS" = "0"
+"SOURCE_CONTROL_SETTINGS_PROVIDER" = "PROVIDER"
+}
--- fsharp-3.1.1.26+dfsg2.orig/FsLex/assemblyinfo.fslex.exe.fs
+++ fsharp-3.1.1.26+dfsg2/FsLex/assemblyinfo.fslex.exe.fs
@@ -1,8 +1,8 @@
-
-namespace Microsoft.FSharp
-open System.Reflection
-[<assembly:AssemblyDescription("fslex.exe")>]
-[<assembly:AssemblyCompany("F# PowerPack CodePlex Project")>]
-[<assembly:AssemblyTitle("fslex.exe")>]
-[<assembly:AssemblyProduct("F# Power Pack")>]
-do()
+
+namespace Microsoft.FSharp
+open System.Reflection
+[<assembly:AssemblyDescription("fslex.exe")>]
+[<assembly:AssemblyCompany("F# PowerPack CodePlex Project")>]
+[<assembly:AssemblyTitle("fslex.exe")>]
+[<assembly:AssemblyProduct("F# Power Pack")>]
+do()
--- fsharp-3.1.1.26+dfsg2.orig/FsLex/fslex.fs
+++ fsharp-3.1.1.26+dfsg2/FsLex/fslex.fs
@@ -1,225 +1,225 @@
-// (c) Microsoft Corporation 2005-2009.  
-
-module internal FSharp.PowerPack.FsLex.Driver 
-
-open FSharp.PowerPack.FsLex
-open FSharp.PowerPack.FsLex.AST
-open FSharp.PowerPack.FsLex.Parser
-open Printf
-open Internal.Utilities
-open Internal.Utilities.Text.Lexing
-open System
-open System.Collections.Generic
-open System.IO 
-
-//------------------------------------------------------------------
-// This code is duplicated from Microsoft.FSharp.Compiler.UnicodeLexing
-
-type Lexbuf =  LexBuffer<char>
-
-/// Standard utility to create a Unicode LexBuffer
-///
-/// One small annoyance is that LexBuffers and not IDisposable. This means 
-/// we can't just return the LexBuffer object, since the file it wraps wouldn't
-/// get closed when we're finished with the LexBuffer. Hence we return the stream,
-/// the reader and the LexBuffer. The caller should dispose the first two when done.
-let UnicodeFileAsLexbuf (filename,codePage : int option) : FileStream * StreamReader * Lexbuf =
-    // Use the .NET functionality to auto-detect the unicode encoding
-    // It also presents the bytes read to the lexer in UTF8 decoded form
-    let stream  = new FileStream(filename,FileMode.Open,FileAccess.Read,FileShare.Read) 
-    let reader = 
-        match codePage with 
-        | None -> new  StreamReader(stream,true)
-        | Some n -> new  StreamReader(stream,System.Text.Encoding.GetEncoding(n)) 
-    let lexbuf = LexBuffer.FromFunction(reader.Read) 
-    lexbuf.EndPos <- Position.FirstLine(filename);
-    stream, reader, lexbuf
-    
-//------------------------------------------------------------------
-// This is the program proper
-
-let input = ref None
-let out = ref None
-let inputCodePage = ref None
-let light = ref None
-
-let mutable lexlib = "Microsoft.FSharp.Text.Lexing"
-
-let usage =
-  [ ArgInfo ("-o", ArgType.String (fun s -> out := Some s), "Name the output file."); 
-    ArgInfo ("--codepage", ArgType.Int (fun i -> inputCodePage := Some i), "Assume input lexer specification file is encoded with the given codepage."); 
-    ArgInfo ("--light", ArgType.Unit (fun () ->  light := Some true), "(ignored)");
-    ArgInfo ("--light-off", ArgType.Unit (fun () ->  light := Some false), "Add #light \"off\" to the top of the generated file");
-    ArgInfo ("--lexlib", ArgType.String (fun s ->  lexlib <- s), "Specify the namespace for the implementation of the lexer table interperter (default Microsoft.FSharp.Text.Lexing)");
-    ArgInfo ("--unicode", ArgType.Set unicode, "Produce a lexer for use with 16-bit unicode characters.");  
-  ]
-
-let _ = ArgParser.Parse(usage, (fun x -> match !input with Some _ -> failwith "more than one input given" | None -> input := Some x), "fslex <filename>")
-
-let outputInt (os: TextWriter) (n:int) = os.Write(string n)
-
-let outputCodedUInt16 (os: #TextWriter)  (n:int) = 
-  os.Write n;
-  os.Write "us; ";
-
-let sentinel = 255 * 256 + 255 
-
-let lineCount = ref 0
-let cfprintfn (os: #TextWriter) fmt = Printf.kfprintf (fun () -> incr lineCount; os.WriteLine()) os fmt
-
-let main() = 
-  try 
-    let filename = (match !input with Some x -> x | None -> failwith "no input given") 
-    let domain = if !unicode then "Unicode" else "Ascii" 
-    let spec = 
-      let stream,reader,lexbuf = UnicodeFileAsLexbuf(filename, !inputCodePage) 
-      use stream = stream
-      use reader = reader
-      try 
-          Parser.spec Lexer.token lexbuf 
-      with e -> 
-          printf "%s(%d,%d): error: %s" filename lexbuf.StartPos.Line lexbuf.StartPos.Column 
-              (match e with 
-               | Failure s -> s 
-               | _ -> e.Message);
-          exit 1
-    printfn "compiling to dfas (can take a while...)";
-    let perRuleData, dfaNodes = AST.Compile spec
-    let dfaNodes = dfaNodes |> List.sortBy (fun n -> n.Id) 
-
-    printfn "%d states" dfaNodes.Length;
-    printfn "writing output"; 
-    
-    let output = 
-        match !out with 
-        | Some x -> x 
-        | _ -> 
-            Path.Combine (Path.GetDirectoryName filename,Path.GetFileNameWithoutExtension(filename)) + ".fs"
-    use os = System.IO.File.CreateText output
-
-    if (!light = Some(false)) || (!light = None && (Path.HasExtension(output) && Path.GetExtension(output) = ".ml")) then
-        cfprintfn os "#light \"off\"";
-    
-    let printLinesIfCodeDefined (code,pos:Position) =
-        if pos <> Position.Empty  // If bottom code is unspecified, then position is empty.        
-        then 
-            cfprintfn os "# %d \"%s\"" pos.Line pos.FileName;
-            cfprintfn os "%s" code;
-
-    printLinesIfCodeDefined spec.TopCode
-    let code = fst spec.TopCode
-    lineCount := !lineCount + code.Replace("\r","").Split([| '\n' |]).Length;
-    cfprintfn os "# %d \"%s\"" !lineCount output;
-    
-    cfprintfn os "let trans : uint16[] array = ";
-    cfprintfn os "    [| ";
-    if !unicode then 
-        let specificUnicodeChars = GetSpecificUnicodeChars()
-        // This emits a (numLowUnicodeChars+NumUnicodeCategories+(2*#specificUnicodeChars)+1) * #states array of encoded UInt16 values
-        
-        // Each row for the Unicode table has format 
-        //      128 entries for ASCII characters
-        //      A variable number of 2*UInt16 entries for SpecificUnicodeChars 
-        //      30 entries, one for each UnicodeCategory
-        //      1 entry for EOF
-        //
-        // Each entry is an encoded UInt16 value indicating the next state to transition to for this input.
-        //
-        // For the SpecificUnicodeChars the entries are char/next-state pairs.
-        for state in dfaNodes do
-            cfprintfn os "    (* State %d *)" state.Id;
-            fprintf os "     [| ";
-            let trans = 
-                let dict = new Dictionary<_,_>()
-                state.Transitions |> List.iter dict.Add
-                dict
-            let emit n = 
-                if trans.ContainsKey(n) then 
-                  outputCodedUInt16 os trans.[n].Id 
-                else
-                  outputCodedUInt16 os sentinel
-            for i = 0 to numLowUnicodeChars-1 do 
-                let c = char i
-                emit (EncodeChar c);
-            for c in specificUnicodeChars do 
-                outputCodedUInt16 os (int c); 
-                emit (EncodeChar c);
-            for i = 0 to NumUnicodeCategories-1 do 
-                emit (EncodeUnicodeCategoryIndex i);
-            emit Eof;
-            cfprintfn os "|];"
-        done;
-    
-    else
-        // Each row for the ASCII table has format 
-        //      256 entries for ASCII characters
-        //      1 entry for EOF
-        //
-        // Each entry is an encoded UInt16 value indicating the next state to transition to for this input.
-
-        // This emits a (256+1) * #states array of encoded UInt16 values
-        for state in dfaNodes do
-            cfprintfn os "   (* State %d *)" state.Id;
-            fprintf os " [|";
-            let trans = 
-                let dict = new Dictionary<_,_>()
-                state.Transitions |> List.iter dict.Add
-                dict
-            let emit n = 
-                if trans.ContainsKey(n) then 
-                  outputCodedUInt16 os trans.[n].Id 
-                else
-                  outputCodedUInt16 os sentinel
-            for i = 0 to 255 do 
-                let c = char i
-                emit (EncodeChar c);
-            emit Eof;
-            cfprintfn os "|];"
-        done;
-    
-    cfprintfn os "    |] ";
-    
-    fprintf os "let actions : uint16[] = [|";
-    for state in dfaNodes do
-        if state.Accepted.Length > 0 then 
-          outputCodedUInt16 os (snd state.Accepted.Head)
-        else
-          outputCodedUInt16 os sentinel
-    done;
-    cfprintfn os "|]";
-    cfprintfn os "let _fslex_tables = %s.%sTables.Create(trans,actions)" lexlib domain;
-    
-    cfprintfn os "let rec _fslex_dummy () = _fslex_dummy() ";
-
-    // These actions push the additional start state and come first, because they are then typically inlined into later
-    // rules. This means more tailcalls are taken as direct branches, increasing efficiency and 
-    // improving stack usage on platforms that do not take tailcalls.
-    for ((startNode, actions),(ident,args,_)) in List.zip perRuleData spec.Rules do
-        cfprintfn os "(* Rule %s *)" ident;
-        cfprintfn os "and %s %s (lexbuf : %s.LexBuffer<_>) = _fslex_%s %s %d lexbuf" ident (String.Join(" ",Array.ofList args)) lexlib ident (String.Join(" ",Array.ofList args)) startNode.Id;
-    for ((startNode, actions),(ident,args,_)) in List.zip perRuleData spec.Rules do
-        cfprintfn os "(* Rule %s *)" ident;
-        cfprintfn os "and _fslex_%s %s _fslex_state lexbuf =" ident (String.Join(" ",Array.ofList args));
-        cfprintfn os "  match _fslex_tables.Interpret(_fslex_state,lexbuf) with" ;
-        actions |> Seq.iteri (fun i (code,pos) -> 
-            cfprintfn os "  | %d -> ( " i;
-            cfprintfn os "# %d \"%s\"" pos.Line pos.FileName;
-            let lines = code.Split([| '\r'; '\n' |], StringSplitOptions.RemoveEmptyEntries)
-            for line in lines do
-                cfprintfn os "               %s" line;
-            cfprintfn os "# %d \"%s\"" !lineCount output;
-            cfprintfn os "          )")
-        cfprintfn os "  | _ -> failwith \"%s\"" ident
-    
-
-    cfprintfn os "";
-        
-    printLinesIfCodeDefined spec.BottomCode
-    cfprintfn os "# 3000000 \"%s\"" output;
-    
-  with e -> 
-    printf "FSLEX: error FSL000: %s" (match e with Failure s -> s | e -> e.ToString());
-    exit 1
-
-
-let _ = main()
+// (c) Microsoft Corporation 2005-2009.  
+
+module internal FSharp.PowerPack.FsLex.Driver 
+
+open FSharp.PowerPack.FsLex
+open FSharp.PowerPack.FsLex.AST
+open FSharp.PowerPack.FsLex.Parser
+open Printf
+open Internal.Utilities
+open Internal.Utilities.Text.Lexing
+open System
+open System.Collections.Generic
+open System.IO 
+
+//------------------------------------------------------------------
+// This code is duplicated from Microsoft.FSharp.Compiler.UnicodeLexing
+
+type Lexbuf =  LexBuffer<char>
+
+/// Standard utility to create a Unicode LexBuffer
+///
+/// One small annoyance is that LexBuffers and not IDisposable. This means 
+/// we can't just return the LexBuffer object, since the file it wraps wouldn't
+/// get closed when we're finished with the LexBuffer. Hence we return the stream,
+/// the reader and the LexBuffer. The caller should dispose the first two when done.
+let UnicodeFileAsLexbuf (filename,codePage : int option) : FileStream * StreamReader * Lexbuf =
+    // Use the .NET functionality to auto-detect the unicode encoding
+    // It also presents the bytes read to the lexer in UTF8 decoded form
+    let stream  = new FileStream(filename,FileMode.Open,FileAccess.Read,FileShare.Read) 
+    let reader = 
+        match codePage with 
+        | None -> new  StreamReader(stream,true)
+        | Some n -> new  StreamReader(stream,System.Text.Encoding.GetEncoding(n)) 
+    let lexbuf = LexBuffer.FromFunction(reader.Read) 
+    lexbuf.EndPos <- Position.FirstLine(filename);
+    stream, reader, lexbuf
+    
+//------------------------------------------------------------------
+// This is the program proper
+
+let input = ref None
+let out = ref None
+let inputCodePage = ref None
+let light = ref None
+
+let mutable lexlib = "Microsoft.FSharp.Text.Lexing"
+
+let usage =
+  [ ArgInfo ("-o", ArgType.String (fun s -> out := Some s), "Name the output file."); 
+    ArgInfo ("--codepage", ArgType.Int (fun i -> inputCodePage := Some i), "Assume input lexer specification file is encoded with the given codepage."); 
+    ArgInfo ("--light", ArgType.Unit (fun () ->  light := Some true), "(ignored)");
+    ArgInfo ("--light-off", ArgType.Unit (fun () ->  light := Some false), "Add #light \"off\" to the top of the generated file");
+    ArgInfo ("--lexlib", ArgType.String (fun s ->  lexlib <- s), "Specify the namespace for the implementation of the lexer table interperter (default Microsoft.FSharp.Text.Lexing)");
+    ArgInfo ("--unicode", ArgType.Set unicode, "Produce a lexer for use with 16-bit unicode characters.");  
+  ]
+
+let _ = ArgParser.Parse(usage, (fun x -> match !input with Some _ -> failwith "more than one input given" | None -> input := Some x), "fslex <filename>")
+
+let outputInt (os: TextWriter) (n:int) = os.Write(string n)
+
+let outputCodedUInt16 (os: #TextWriter)  (n:int) = 
+  os.Write n;
+  os.Write "us; ";
+
+let sentinel = 255 * 256 + 255 
+
+let lineCount = ref 0
+let cfprintfn (os: #TextWriter) fmt = Printf.kfprintf (fun () -> incr lineCount; os.WriteLine()) os fmt
+
+let main() = 
+  try 
+    let filename = (match !input with Some x -> x | None -> failwith "no input given") 
+    let domain = if !unicode then "Unicode" else "Ascii" 
+    let spec = 
+      let stream,reader,lexbuf = UnicodeFileAsLexbuf(filename, !inputCodePage) 
+      use stream = stream
+      use reader = reader
+      try 
+          Parser.spec Lexer.token lexbuf 
+      with e -> 
+          printf "%s(%d,%d): error: %s" filename lexbuf.StartPos.Line lexbuf.StartPos.Column 
+              (match e with 
+               | Failure s -> s 
+               | _ -> e.Message);
+          exit 1
+    printfn "compiling to dfas (can take a while...)";
+    let perRuleData, dfaNodes = AST.Compile spec
+    let dfaNodes = dfaNodes |> List.sortBy (fun n -> n.Id) 
+
+    printfn "%d states" dfaNodes.Length;
+    printfn "writing output"; 
+    
+    let output = 
+        match !out with 
+        | Some x -> x 
+        | _ -> 
+            Path.Combine (Path.GetDirectoryName filename,Path.GetFileNameWithoutExtension(filename)) + ".fs"
+    use os = System.IO.File.CreateText output
+
+    if (!light = Some(false)) || (!light = None && (Path.HasExtension(output) && Path.GetExtension(output) = ".ml")) then
+        cfprintfn os "#light \"off\"";
+    
+    let printLinesIfCodeDefined (code,pos:Position) =
+        if pos <> Position.Empty  // If bottom code is unspecified, then position is empty.        
+        then 
+            cfprintfn os "# %d \"%s\"" pos.Line pos.FileName;
+            cfprintfn os "%s" code;
+
+    printLinesIfCodeDefined spec.TopCode
+    let code = fst spec.TopCode
+    lineCount := !lineCount + code.Replace("\r","").Split([| '\n' |]).Length;
+    cfprintfn os "# %d \"%s\"" !lineCount output;
+    
+    cfprintfn os "let trans : uint16[] array = ";
+    cfprintfn os "    [| ";
+    if !unicode then 
+        let specificUnicodeChars = GetSpecificUnicodeChars()
+        // This emits a (numLowUnicodeChars+NumUnicodeCategories+(2*#specificUnicodeChars)+1) * #states array of encoded UInt16 values
+        
+        // Each row for the Unicode table has format 
+        //      128 entries for ASCII characters
+        //      A variable number of 2*UInt16 entries for SpecificUnicodeChars 
+        //      30 entries, one for each UnicodeCategory
+        //      1 entry for EOF
+        //
+        // Each entry is an encoded UInt16 value indicating the next state to transition to for this input.
+        //
+        // For the SpecificUnicodeChars the entries are char/next-state pairs.
+        for state in dfaNodes do
+            cfprintfn os "    (* State %d *)" state.Id;
+            fprintf os "     [| ";
+            let trans = 
+                let dict = new Dictionary<_,_>()
+                state.Transitions |> List.iter dict.Add
+                dict
+            let emit n = 
+                if trans.ContainsKey(n) then 
+                  outputCodedUInt16 os trans.[n].Id 
+                else
+                  outputCodedUInt16 os sentinel
+            for i = 0 to numLowUnicodeChars-1 do 
+                let c = char i
+                emit (EncodeChar c);
+            for c in specificUnicodeChars do 
+                outputCodedUInt16 os (int c); 
+                emit (EncodeChar c);
+            for i = 0 to NumUnicodeCategories-1 do 
+                emit (EncodeUnicodeCategoryIndex i);
+            emit Eof;
+            cfprintfn os "|];"
+        done;
+    
+    else
+        // Each row for the ASCII table has format 
+        //      256 entries for ASCII characters
+        //      1 entry for EOF
+        //
+        // Each entry is an encoded UInt16 value indicating the next state to transition to for this input.
+
+        // This emits a (256+1) * #states array of encoded UInt16 values
+        for state in dfaNodes do
+            cfprintfn os "   (* State %d *)" state.Id;
+            fprintf os " [|";
+            let trans = 
+                let dict = new Dictionary<_,_>()
+                state.Transitions |> List.iter dict.Add
+                dict
+            let emit n = 
+                if trans.ContainsKey(n) then 
+                  outputCodedUInt16 os trans.[n].Id 
+                else
+                  outputCodedUInt16 os sentinel
+            for i = 0 to 255 do 
+                let c = char i
+                emit (EncodeChar c);
+            emit Eof;
+            cfprintfn os "|];"
+        done;
+    
+    cfprintfn os "    |] ";
+    
+    fprintf os "let actions : uint16[] = [|";
+    for state in dfaNodes do
+        if state.Accepted.Length > 0 then 
+          outputCodedUInt16 os (snd state.Accepted.Head)
+        else
+          outputCodedUInt16 os sentinel
+    done;
+    cfprintfn os "|]";
+    cfprintfn os "let _fslex_tables = %s.%sTables.Create(trans,actions)" lexlib domain;
+    
+    cfprintfn os "let rec _fslex_dummy () = _fslex_dummy() ";
+
+    // These actions push the additional start state and come first, because they are then typically inlined into later
+    // rules. This means more tailcalls are taken as direct branches, increasing efficiency and 
+    // improving stack usage on platforms that do not take tailcalls.
+    for ((startNode, actions),(ident,args,_)) in List.zip perRuleData spec.Rules do
+        cfprintfn os "(* Rule %s *)" ident;
+        cfprintfn os "and %s %s (lexbuf : %s.LexBuffer<_>) = _fslex_%s %s %d lexbuf" ident (String.Join(" ",Array.ofList args)) lexlib ident (String.Join(" ",Array.ofList args)) startNode.Id;
+    for ((startNode, actions),(ident,args,_)) in List.zip perRuleData spec.Rules do
+        cfprintfn os "(* Rule %s *)" ident;
+        cfprintfn os "and _fslex_%s %s _fslex_state lexbuf =" ident (String.Join(" ",Array.ofList args));
+        cfprintfn os "  match _fslex_tables.Interpret(_fslex_state,lexbuf) with" ;
+        actions |> Seq.iteri (fun i (code,pos) -> 
+            cfprintfn os "  | %d -> ( " i;
+            cfprintfn os "# %d \"%s\"" pos.Line pos.FileName;
+            let lines = code.Split([| '\r'; '\n' |], StringSplitOptions.RemoveEmptyEntries)
+            for line in lines do
+                cfprintfn os "               %s" line;
+            cfprintfn os "# %d \"%s\"" !lineCount output;
+            cfprintfn os "          )")
+        cfprintfn os "  | _ -> failwith \"%s\"" ident
+    
+
+    cfprintfn os "";
+        
+    printLinesIfCodeDefined spec.BottomCode
+    cfprintfn os "# 3000000 \"%s\"" output;
+    
+  with e -> 
+    printf "FSLEX: error FSL000: %s" (match e with Failure s -> s | e -> e.ToString());
+    exit 1
+
+
+let _ = main()
--- fsharp-3.1.1.26+dfsg2.orig/FsLex/fslexast.fs
+++ fsharp-3.1.1.26+dfsg2/FsLex/fslexast.fs
@@ -1,409 +1,409 @@
-(* (c) Microsoft Corporation 2005-2008.  *)
-
-module FSharp.PowerPack.FsLex.AST
-
-open System.Collections.Generic
-open Microsoft.FSharp.Text
-open Microsoft.FSharp.Collections
-open Internal.Utilities
-open Internal.Utilities.Text.Lexing
-
-let (|KeyValue|) (kvp:KeyValuePair<_,_>) = kvp.Key,kvp.Value
-
-type Ident = string
-type Code = string * Position
-
-type Alphabet = uint32
-
-let Eof : Alphabet = 0xFFFFFFFEu
-let Epsilon : Alphabet = 0xFFFFFFFFu
-
-
-let unicode = ref false
-
-let unicodeCategories = 
- dict 
-  [| "Pe", System.Globalization.UnicodeCategory.ClosePunctuation; // (Pe)
-    "Pc", System.Globalization.UnicodeCategory.ConnectorPunctuation; // (Pc)
-    "Cc", System.Globalization.UnicodeCategory.Control; // (Cc)
-    "Sc", System.Globalization.UnicodeCategory.CurrencySymbol; // (Sc)
-    "Pd", System.Globalization.UnicodeCategory.DashPunctuation; // (Pd)
-    "Nd", System.Globalization.UnicodeCategory.DecimalDigitNumber; // (Nd)
-    "Me", System.Globalization.UnicodeCategory.EnclosingMark; // (Me)
-    "Pf", System.Globalization.UnicodeCategory.FinalQuotePunctuation; // (Pf)
-    "Cf", enum 15; //System.Globalization.UnicodeCategory.Format; // (Cf)
-    "Pi", System.Globalization.UnicodeCategory.InitialQuotePunctuation; // (Pi)
-    "Nl", System.Globalization.UnicodeCategory.LetterNumber; // (Nl)
-    "Zl", System.Globalization.UnicodeCategory.LineSeparator; // (Zl)
-    "Ll", System.Globalization.UnicodeCategory.LowercaseLetter; // (Ll)
-    "Sm", System.Globalization.UnicodeCategory.MathSymbol; // (Sm)
-    "Lm", System.Globalization.UnicodeCategory.ModifierLetter; // (Lm)
-    "Sk", System.Globalization.UnicodeCategory.ModifierSymbol; // (Sk)
-    "Mn", System.Globalization.UnicodeCategory.NonSpacingMark; // (Mn)
-    "Ps", System.Globalization.UnicodeCategory.OpenPunctuation; // (Ps)
-    "Lo", System.Globalization.UnicodeCategory.OtherLetter; // (Lo)
-    "Cn", System.Globalization.UnicodeCategory.OtherNotAssigned; // (Cn)
-    "No", System.Globalization.UnicodeCategory.OtherNumber; // (No)
-    "Po", System.Globalization.UnicodeCategory.OtherPunctuation; // (Po)
-    "So", System.Globalization.UnicodeCategory.OtherSymbol; // (So)
-    "Zp", System.Globalization.UnicodeCategory.ParagraphSeparator; // (Zp)
-    "Co", System.Globalization.UnicodeCategory.PrivateUse; // (Co)
-    "Zs", System.Globalization.UnicodeCategory.SpaceSeparator; // (Zs)
-    "Mc", System.Globalization.UnicodeCategory.SpacingCombiningMark; // (Mc)
-    "Cs", System.Globalization.UnicodeCategory.Surrogate; // (Cs)
-    "Lt", System.Globalization.UnicodeCategory.TitlecaseLetter; // (Lt)
-    "Lu", System.Globalization.UnicodeCategory.UppercaseLetter; // (Lu)
-  |]
-
-let NumUnicodeCategories = unicodeCategories.Count
-let _ = assert (NumUnicodeCategories = 30) // see table interpreter
-let encodedUnicodeCategoryBase = 0xFFFFFF00u
-let EncodeUnicodeCategoryIndex(idx:int) = encodedUnicodeCategoryBase + uint32 idx
-let EncodeUnicodeCategory(s:string) = 
-    if not (!unicode) then 
-         failwith "unicode category classes may only be used if --unicode is specified";
-    if unicodeCategories.ContainsKey(s) then 
-        EncodeUnicodeCategoryIndex (int32 unicodeCategories.[s])
-    else
-        failwithf "invalid Unicode category: '%s'" s
-
-let IsUnicodeCategory(x:Alphabet) = (encodedUnicodeCategoryBase <= x) && (x < encodedUnicodeCategoryBase + uint32 NumUnicodeCategories)
-let UnicodeCategoryIndex(x:Alphabet) = (x - encodedUnicodeCategoryBase)
-
-let numLowUnicodeChars = 128
-let _ = assert (numLowUnicodeChars = 128) // see table interpreter
-let specificUnicodeChars = new Dictionary<_,_>()
-let specificUnicodeCharsDecode = new Dictionary<_,_>()
-let EncodeChar(c:char) = 
-     let x = System.Convert.ToUInt32 c
-     if !unicode then 
-         if x < uint32 numLowUnicodeChars then x 
-         else 
-             if not(specificUnicodeChars.ContainsKey(c)) then
-                 let idx = uint32 numLowUnicodeChars + uint32 specificUnicodeChars.Count  
-                 specificUnicodeChars.[c] <- idx
-                 specificUnicodeCharsDecode.[idx] <- c
-             specificUnicodeChars.[c]
-     else         
-         if x >= 256u then failwithf "the Unicode character '%c' may not be used unless --unicode is specified" c;
-         x
-let DecodeChar(x:Alphabet) = 
-     if !unicode then 
-         if x < uint32 numLowUnicodeChars then System.Convert.ToChar x
-         else specificUnicodeCharsDecode.[x]
-     else
-         if x >= 256u then failwithf "the Unicode character '%x' may not be used unless --unicode is specified" x;
-         System.Convert.ToChar x
-         
-         
-
-let NumSpecificUnicodeChars() = specificUnicodeChars.Count
-let GetSpecificUnicodeChars() = 
-    specificUnicodeChars 
-        |> Seq.sortBy (fun (KeyValue(k,v)) -> v) 
-        |> Seq.map (fun (KeyValue(k,v)) -> k) 
-
-let GetSingleCharAlphabet() = 
-    if !unicode 
-    then Set.ofList [ for c in 0..numLowUnicodeChars-1 do yield (char c)
-                      for c in GetSpecificUnicodeChars() do yield c ]
-    else Set.ofList [ for x in 0..255 ->  (char x) ]
-         
-let GetAlphabet() = 
-    if !unicode 
-    then Set.ofList [ for c in GetSingleCharAlphabet() do yield EncodeChar c
-                      for uc in 0 .. NumUnicodeCategories-1 do yield EncodeUnicodeCategoryIndex uc ]
-    else Set.ofList [ for c in GetSingleCharAlphabet() do yield EncodeChar c ]
-
-         
-//let DecodeAlphabet (x:Alphabet) = System.Convert.ToChar(x)
-
-(*
-for i in 0 .. 65535 do 
-    let c = char i
-    if System.Char.GetUnicodeCategory c = System.Globalization.UnicodeCategory.PrivateUse then 
-        printfn "i = %x" i
-*)
-
-type Spec = 
-    { TopCode: Code;
-      Macros: (Ident * Regexp) list;
-      Rules: (Ident * Ident list * Clause list) list;
-      BottomCode: Code }
-and Clause = Regexp * Code
-and Regexp = 
-  | Alt of Regexp list
-  | Seq of Regexp list
-  | Inp of Input
-  | Star of Regexp
-  | Macro of Ident
-and Input =
-  | Alphabet of Alphabet
-  | UnicodeCategory of string 
-  | Any 
-  | NotCharSet of Set<Alphabet>
-
-type NodeId = int   
-
-type NfaNode = 
-    { Id: NodeId;
-      Name: string;
-      Transitions: Dictionary<Alphabet, NfaNode list>;
-      Accepted: (int * int) list }
-
-type DfaNode = 
-    { Id: int;
-      Name: string;
-      mutable Transitions: (Alphabet * DfaNode) list;
-      Accepted: (int * int) list }
-
-type MultiMap<'a,'b> = Dictionary<'a,'b list>
-let LookupMultiMap (trDict:MultiMap<_,_>) a  =
-    if trDict.ContainsKey(a) then trDict.[a] else []
-
-let AddToMultiMap (trDict:MultiMap<_,_>) a b =
-    let prev = LookupMultiMap trDict a
-    trDict.[a] <- b::prev
-
-type NfaNodeMap() = 
-    let map = new Dictionary<int,NfaNode>(100)
-    member x.Item with get(nid) = map.[nid]
-    member x.Count = map.Count
-
-    member x.NewNfaNode(trs,ac) = 
-        let nodeId = map.Count+1 // ID zero is reserved
-        let trDict = new Dictionary<_,_>(List.length trs)
-        for (a,b) in trs do
-           AddToMultiMap trDict a b
-           
-        let node : NfaNode = {Id=nodeId; Name=string nodeId; Transitions=trDict; Accepted=ac}
-        map.[nodeId] <-node;
-        node
-
-let LexerStateToNfa (macros: Map<string,_>) (clauses: Clause list) = 
-
-    /// Table allocating node ids 
-    let nfaNodeMap = new NfaNodeMap()
-    
-    /// Compile a regular expression into the NFA
-    let rec CompileRegexp re dest = 
-        match re with 
-        | Alt res -> 
-            let trs = res |> List.map (fun re -> (Epsilon,CompileRegexp re dest)) 
-            nfaNodeMap.NewNfaNode(trs,[])
-        | Seq res -> 
-            List.foldBack (CompileRegexp) res dest 
-        | Inp (Alphabet c) -> 
-            nfaNodeMap.NewNfaNode([(c, dest)],[])
-            
-        | Star re -> 
-            let nfaNode = nfaNodeMap.NewNfaNode([(Epsilon, dest)],[])
-            let sre = CompileRegexp re nfaNode
-            AddToMultiMap nfaNode.Transitions Epsilon sre
-            nfaNodeMap.NewNfaNode([(Epsilon,sre); (Epsilon,dest)],[])
-        | Macro m -> 
-            if not (macros.ContainsKey(m)) then failwith ("The macro "+m+" is not defined");
-            CompileRegexp (macros.[m]) dest 
-
-        // These cases unwind the difficult cases in the syntax that rely on knowing the
-        // entire alphabet.
-        //
-        // Note we've delayed the expension of these until we've worked out all the 'special' Unicode characters
-        // mentioned in the entire lexer spec, i.e. we wait until GetAlphabet returns a reliable and stable answer.
-        | Inp (UnicodeCategory uc) -> 
-            let re = Alt([ yield Inp(Alphabet(EncodeUnicodeCategory uc))
-                           // Also include any specific characters in this category
-                           for c in GetSingleCharAlphabet() do 
-                               if System.Char.GetUnicodeCategory(c) = unicodeCategories.[uc] then 
-                                    yield Inp(Alphabet(EncodeChar(c))) ])
-            CompileRegexp re dest
-
-        | Inp Any -> 
-            let re = Alt([ for n in GetAlphabet() do yield Inp(Alphabet(n)) ])
-            CompileRegexp re dest
-
-        | Inp (NotCharSet chars) -> 
-            let re = Alt [ // Include any characters from those in the alphabet besides those that are not immediately excluded
-                           for c in GetSingleCharAlphabet() do 
-                               let ec = EncodeChar c
-                               if not (chars.Contains(ec)) then 
-                                   yield Inp(Alphabet(ec))
-
-                           // Include all unicode categories 
-                           // That is, negations _only_ exclude precisely the given set of characters. You can't
-                           // exclude whole classes of characters as yet
-                           if !unicode then 
-                               let ucs = chars |> Set.map(DecodeChar >> System.Char.GetUnicodeCategory)  
-                               for KeyValue(nm,uc) in unicodeCategories do
-                                   //if ucs.Contains(uc) then 
-                                   //    do printfn "warning: the unicode category '\\%s' ('%s') is automatically excluded by this character set negation. Consider adding this to the negation." nm  (uc.ToString())
-                                   //    yield! []
-                                   //else
-                                       yield Inp(Alphabet(EncodeUnicodeCategory nm)) 
-                         ]
-            CompileRegexp re dest
-
-    let actions = new System.Collections.Generic.List<_>()
-    
-    /// Compile an acceptance of a regular expression into the NFA
-    let sTrans macros nodeId (regexp,code) = 
-        let actionId = actions.Count
-        actions.Add(code)
-        let sAccept = nfaNodeMap.NewNfaNode([],[(nodeId,actionId)])
-        CompileRegexp regexp sAccept 
-
-    let trs = clauses |> List.mapi (fun n x -> (Epsilon,sTrans macros n x)) 
-    let nfaStartNode = nfaNodeMap.NewNfaNode(trs,[])
-    nfaStartNode,(actions |> Seq.readonly), nfaNodeMap
-
-// TODO: consider a better representation here.
-type internal NfaNodeIdSetBuilder = HashSet<NodeId>
-
-type internal NfaNodeIdSet(nodes: NfaNodeIdSetBuilder) = 
-    // BEWARE: the next line is performance critical
-    let s = nodes |> Seq.toArray |> (fun arr -> Array.sortInPlaceWith compare arr; arr) // 19
-
-    // These are all surprisingly slower:
-    //let s = nodes |> Seq.toArray |> Array.sort 
-    //let s = nodes |> Seq.toArray |> Array.sortWith compare // 76
-    //let s = nodes |> Seq.toArray |> (fun arr -> Array.sortInPlace arr; arr) // 76
-
-    member x.Representation = s
-    member x.Elements = s 
-    member x.Fold f z = Array.fold f z s
-    interface System.IComparable with 
-        member x.CompareTo(y:obj) = 
-            let y = (y :?> NfaNodeIdSet)
-            let xr = x.Representation
-            let yr = y.Representation
-            let c = compare xr.Length yr.Length
-            if c <> 0 then c else 
-            let n = yr.Length
-            let rec go i = 
-                if i >= n then 0 else
-                let c = compare xr.[i] yr.[i]
-                if c <> 0 then c else
-                go (i+1) 
-            go 0
-
-    override x.Equals(y:obj) = 
-        match y with 
-        | :? NfaNodeIdSet as y -> 
-            let xr = x.Representation
-            let yr = y.Representation
-            let n = yr.Length
-            xr.Length = n && 
-            (let rec go i = (i < n) && xr.[i] = yr.[i] && go (i+1) 
-             go 0)
-        | _ -> false
-
-    override x.GetHashCode() = hash s
-
-    member x.IsEmpty = (s.Length = 0)
-    member x.Iterate f = s |> Array.iter f
-
-type NodeSetSet = Set<NfaNodeIdSet>
-
-let newDfaNodeId = 
-    let i = ref 0 
-    fun () -> let res = !i in incr i; res
-   
-let NfaToDfa (nfaNodeMap:NfaNodeMap) nfaStartNode = 
-    let numNfaNodes = nfaNodeMap.Count
-    let rec EClosure1 (acc:NfaNodeIdSetBuilder) (n:NfaNode) = 
-        if not (acc.Contains(n.Id)) then 
-            acc.Add(n.Id) |> ignore;
-            if n.Transitions.ContainsKey(Epsilon) then
-                match n.Transitions.[Epsilon] with 
-                | [] -> () // this Clause is an optimization - the list is normally empty
-                | tr -> 
-                    //printfn "n.Id = %A, #Epsilon = %d" n.Id tr.Length
-                    tr |> List.iter (EClosure1 acc) 
-
-    let EClosure (moves:list<NodeId>) = 
-        let acc = new NfaNodeIdSetBuilder(HashIdentity.Structural)
-        for i in moves do
-            EClosure1 acc nfaNodeMap.[i];
-        new NfaNodeIdSet(acc)
-
-    // Compute all the immediate one-step moves for a set of NFA states, as a dictionary
-    // mapping inputs to destination lists
-    let ComputeMoves (nset:NfaNodeIdSet) = 
-        let moves = new MultiMap<_,_>()
-        nset.Iterate(fun nodeId -> 
-            for (KeyValue(inp,dests)) in nfaNodeMap.[nodeId].Transitions do
-                if inp <> Epsilon then 
-                    match dests with 
-                    | [] -> ()  // this Clause is an optimization - the list is normally empty
-                    | tr -> tr |> List.iter(fun dest -> AddToMultiMap moves inp dest.Id))
-        moves
-
-    let acc = new NfaNodeIdSetBuilder(HashIdentity.Structural)
-    EClosure1 acc nfaStartNode;
-    let nfaSet0 = new NfaNodeIdSet(acc)
-
-    let dfaNodes = ref (Map.empty<NfaNodeIdSet,DfaNode>)
-
-    let GetDfaNode nfaSet = 
-        if (!dfaNodes).ContainsKey(nfaSet) then 
-            (!dfaNodes).[nfaSet]
-        else 
-            let dfaNode =
-                { Id= newDfaNodeId(); 
-                  Name = nfaSet.Fold (fun s nid -> nfaNodeMap.[nid].Name+"-"+s) ""; 
-                  Transitions=[];
-                  Accepted= nfaSet.Elements 
-                            |> Seq.map (fun nid -> nfaNodeMap.[nid].Accepted)
-                            |> List.concat }
-            //Printf.printfn "id = %d" dfaNode.Id;
-
-            dfaNodes := (!dfaNodes).Add(nfaSet,dfaNode); 
-            dfaNode
-            
-    let workList = ref [nfaSet0]
-    let doneSet = ref Set.empty
-
-    //let count = ref 0 
-    let rec Loop () = 
-        match !workList with 
-        | [] -> ()
-        | nfaSet ::t -> 
-            workList := t;
-            if (!doneSet).Contains(nfaSet) then 
-                Loop () 
-            else
-                let moves = ComputeMoves nfaSet
-                for (KeyValue(inp,movesForInput)) in moves do
-                    assert (inp <> Epsilon);
-                    let moveSet = EClosure movesForInput;
-                    if not moveSet.IsEmpty then 
-                        //incr count
-                        let dfaNode = GetDfaNode nfaSet
-                        dfaNode.Transitions <- (inp, GetDfaNode moveSet) :: dfaNode.Transitions;
-                        (* Printf.printf "%d (%s) : %s --> %d (%s)\n" dfaNode.Id dfaNode.Name (match inp with EncodeChar c -> String.make 1 c | LEof -> "eof") moveSetDfaNode.Id moveSetDfaNode.Name;*)
-                        workList := moveSet :: !workList;
-
-                doneSet := (!doneSet).Add(nfaSet);
-
-
-                Loop()
-    Loop();
-    //Printf.printfn "count = %d" !count;
-    let ruleStartNode = GetDfaNode nfaSet0
-    let ruleNodes = 
-        (!dfaNodes) 
-        |> Seq.map (fun kvp -> kvp.Value) 
-        |> Seq.toList
-        |> List.sortBy (fun s -> s.Id)
-    ruleStartNode,ruleNodes
-
-let Compile spec = 
-    List.foldBack
-        (fun (name,args,clauses) (perRuleData,dfaNodes) -> 
-            let nfa, actions, nfaNodeMap = LexerStateToNfa (Map.ofList spec.Macros) clauses
-            let ruleStartNode, ruleNodes = NfaToDfa nfaNodeMap nfa
-            //Printf.printfn "name = %s, ruleStartNode = %O" name ruleStartNode.Id;
-            (ruleStartNode,actions) :: perRuleData, ruleNodes @ dfaNodes)
-        spec.Rules
-        ([],[])
-
+(* (c) Microsoft Corporation 2005-2008.  *)
+
+module FSharp.PowerPack.FsLex.AST
+
+open System.Collections.Generic
+open Microsoft.FSharp.Text
+open Microsoft.FSharp.Collections
+open Internal.Utilities
+open Internal.Utilities.Text.Lexing
+
+let (|KeyValue|) (kvp:KeyValuePair<_,_>) = kvp.Key,kvp.Value
+
+type Ident = string
+type Code = string * Position
+
+type Alphabet = uint32
+
+let Eof : Alphabet = 0xFFFFFFFEu
+let Epsilon : Alphabet = 0xFFFFFFFFu
+
+
+let unicode = ref false
+
+let unicodeCategories = 
+ dict 
+  [| "Pe", System.Globalization.UnicodeCategory.ClosePunctuation; // (Pe)
+    "Pc", System.Globalization.UnicodeCategory.ConnectorPunctuation; // (Pc)
+    "Cc", System.Globalization.UnicodeCategory.Control; // (Cc)
+    "Sc", System.Globalization.UnicodeCategory.CurrencySymbol; // (Sc)
+    "Pd", System.Globalization.UnicodeCategory.DashPunctuation; // (Pd)
+    "Nd", System.Globalization.UnicodeCategory.DecimalDigitNumber; // (Nd)
+    "Me", System.Globalization.UnicodeCategory.EnclosingMark; // (Me)
+    "Pf", System.Globalization.UnicodeCategory.FinalQuotePunctuation; // (Pf)
+    "Cf", enum 15; //System.Globalization.UnicodeCategory.Format; // (Cf)
+    "Pi", System.Globalization.UnicodeCategory.InitialQuotePunctuation; // (Pi)
+    "Nl", System.Globalization.UnicodeCategory.LetterNumber; // (Nl)
+    "Zl", System.Globalization.UnicodeCategory.LineSeparator; // (Zl)
+    "Ll", System.Globalization.UnicodeCategory.LowercaseLetter; // (Ll)
+    "Sm", System.Globalization.UnicodeCategory.MathSymbol; // (Sm)
+    "Lm", System.Globalization.UnicodeCategory.ModifierLetter; // (Lm)
+    "Sk", System.Globalization.UnicodeCategory.ModifierSymbol; // (Sk)
+    "Mn", System.Globalization.UnicodeCategory.NonSpacingMark; // (Mn)
+    "Ps", System.Globalization.UnicodeCategory.OpenPunctuation; // (Ps)
+    "Lo", System.Globalization.UnicodeCategory.OtherLetter; // (Lo)
+    "Cn", System.Globalization.UnicodeCategory.OtherNotAssigned; // (Cn)
+    "No", System.Globalization.UnicodeCategory.OtherNumber; // (No)
+    "Po", System.Globalization.UnicodeCategory.OtherPunctuation; // (Po)
+    "So", System.Globalization.UnicodeCategory.OtherSymbol; // (So)
+    "Zp", System.Globalization.UnicodeCategory.ParagraphSeparator; // (Zp)
+    "Co", System.Globalization.UnicodeCategory.PrivateUse; // (Co)
+    "Zs", System.Globalization.UnicodeCategory.SpaceSeparator; // (Zs)
+    "Mc", System.Globalization.UnicodeCategory.SpacingCombiningMark; // (Mc)
+    "Cs", System.Globalization.UnicodeCategory.Surrogate; // (Cs)
+    "Lt", System.Globalization.UnicodeCategory.TitlecaseLetter; // (Lt)
+    "Lu", System.Globalization.UnicodeCategory.UppercaseLetter; // (Lu)
+  |]
+
+let NumUnicodeCategories = unicodeCategories.Count
+let _ = assert (NumUnicodeCategories = 30) // see table interpreter
+let encodedUnicodeCategoryBase = 0xFFFFFF00u
+let EncodeUnicodeCategoryIndex(idx:int) = encodedUnicodeCategoryBase + uint32 idx
+let EncodeUnicodeCategory(s:string) = 
+    if not (!unicode) then 
+         failwith "unicode category classes may only be used if --unicode is specified";
+    if unicodeCategories.ContainsKey(s) then 
+        EncodeUnicodeCategoryIndex (int32 unicodeCategories.[s])
+    else
+        failwithf "invalid Unicode category: '%s'" s
+
+let IsUnicodeCategory(x:Alphabet) = (encodedUnicodeCategoryBase <= x) && (x < encodedUnicodeCategoryBase + uint32 NumUnicodeCategories)
+let UnicodeCategoryIndex(x:Alphabet) = (x - encodedUnicodeCategoryBase)
+
+let numLowUnicodeChars = 128
+let _ = assert (numLowUnicodeChars = 128) // see table interpreter
+let specificUnicodeChars = new Dictionary<_,_>()
+let specificUnicodeCharsDecode = new Dictionary<_,_>()
+let EncodeChar(c:char) = 
+     let x = System.Convert.ToUInt32 c
+     if !unicode then 
+         if x < uint32 numLowUnicodeChars then x 
+         else 
+             if not(specificUnicodeChars.ContainsKey(c)) then
+                 let idx = uint32 numLowUnicodeChars + uint32 specificUnicodeChars.Count  
+                 specificUnicodeChars.[c] <- idx
+                 specificUnicodeCharsDecode.[idx] <- c
+             specificUnicodeChars.[c]
+     else         
+         if x >= 256u then failwithf "the Unicode character '%c' may not be used unless --unicode is specified" c;
+         x
+let DecodeChar(x:Alphabet) = 
+     if !unicode then 
+         if x < uint32 numLowUnicodeChars then System.Convert.ToChar x
+         else specificUnicodeCharsDecode.[x]
+     else
+         if x >= 256u then failwithf "the Unicode character '%x' may not be used unless --unicode is specified" x;
+         System.Convert.ToChar x
+         
+         
+
+let NumSpecificUnicodeChars() = specificUnicodeChars.Count
+let GetSpecificUnicodeChars() = 
+    specificUnicodeChars 
+        |> Seq.sortBy (fun (KeyValue(k,v)) -> v) 
+        |> Seq.map (fun (KeyValue(k,v)) -> k) 
+
+let GetSingleCharAlphabet() = 
+    if !unicode 
+    then Set.ofList [ for c in 0..numLowUnicodeChars-1 do yield (char c)
+                      for c in GetSpecificUnicodeChars() do yield c ]
+    else Set.ofList [ for x in 0..255 ->  (char x) ]
+         
+let GetAlphabet() = 
+    if !unicode 
+    then Set.ofList [ for c in GetSingleCharAlphabet() do yield EncodeChar c
+                      for uc in 0 .. NumUnicodeCategories-1 do yield EncodeUnicodeCategoryIndex uc ]
+    else Set.ofList [ for c in GetSingleCharAlphabet() do yield EncodeChar c ]
+
+         
+//let DecodeAlphabet (x:Alphabet) = System.Convert.ToChar(x)
+
+(*
+for i in 0 .. 65535 do 
+    let c = char i
+    if System.Char.GetUnicodeCategory c = System.Globalization.UnicodeCategory.PrivateUse then 
+        printfn "i = %x" i
+*)
+
+type Spec = 
+    { TopCode: Code;
+      Macros: (Ident * Regexp) list;
+      Rules: (Ident * Ident list * Clause list) list;
+      BottomCode: Code }
+and Clause = Regexp * Code
+and Regexp = 
+  | Alt of Regexp list
+  | Seq of Regexp list
+  | Inp of Input
+  | Star of Regexp
+  | Macro of Ident
+and Input =
+  | Alphabet of Alphabet
+  | UnicodeCategory of string 
+  | Any 
+  | NotCharSet of Set<Alphabet>
+
+type NodeId = int   
+
+type NfaNode = 
+    { Id: NodeId;
+      Name: string;
+      Transitions: Dictionary<Alphabet, NfaNode list>;
+      Accepted: (int * int) list }
+
+type DfaNode = 
+    { Id: int;
+      Name: string;
+      mutable Transitions: (Alphabet * DfaNode) list;
+      Accepted: (int * int) list }
+
+type MultiMap<'a,'b> = Dictionary<'a,'b list>
+let LookupMultiMap (trDict:MultiMap<_,_>) a  =
+    if trDict.ContainsKey(a) then trDict.[a] else []
+
+let AddToMultiMap (trDict:MultiMap<_,_>) a b =
+    let prev = LookupMultiMap trDict a
+    trDict.[a] <- b::prev
+
+type NfaNodeMap() = 
+    let map = new Dictionary<int,NfaNode>(100)
+    member x.Item with get(nid) = map.[nid]
+    member x.Count = map.Count
+
+    member x.NewNfaNode(trs,ac) = 
+        let nodeId = map.Count+1 // ID zero is reserved
+        let trDict = new Dictionary<_,_>(List.length trs)
+        for (a,b) in trs do
+           AddToMultiMap trDict a b
+           
+        let node : NfaNode = {Id=nodeId; Name=string nodeId; Transitions=trDict; Accepted=ac}
+        map.[nodeId] <-node;
+        node
+
+let LexerStateToNfa (macros: Map<string,_>) (clauses: Clause list) = 
+
+    /// Table allocating node ids 
+    let nfaNodeMap = new NfaNodeMap()
+    
+    /// Compile a regular expression into the NFA
+    let rec CompileRegexp re dest = 
+        match re with 
+        | Alt res -> 
+            let trs = res |> List.map (fun re -> (Epsilon,CompileRegexp re dest)) 
+            nfaNodeMap.NewNfaNode(trs,[])
+        | Seq res -> 
+            List.foldBack (CompileRegexp) res dest 
+        | Inp (Alphabet c) -> 
+            nfaNodeMap.NewNfaNode([(c, dest)],[])
+            
+        | Star re -> 
+            let nfaNode = nfaNodeMap.NewNfaNode([(Epsilon, dest)],[])
+            let sre = CompileRegexp re nfaNode
+            AddToMultiMap nfaNode.Transitions Epsilon sre
+            nfaNodeMap.NewNfaNode([(Epsilon,sre); (Epsilon,dest)],[])
+        | Macro m -> 
+            if not (macros.ContainsKey(m)) then failwith ("The macro "+m+" is not defined");
+            CompileRegexp (macros.[m]) dest 
+
+        // These cases unwind the difficult cases in the syntax that rely on knowing the
+        // entire alphabet.
+        //
+        // Note we've delayed the expension of these until we've worked out all the 'special' Unicode characters
+        // mentioned in the entire lexer spec, i.e. we wait until GetAlphabet returns a reliable and stable answer.
+        | Inp (UnicodeCategory uc) -> 
+            let re = Alt([ yield Inp(Alphabet(EncodeUnicodeCategory uc))
+                           // Also include any specific characters in this category
+                           for c in GetSingleCharAlphabet() do 
+                               if System.Char.GetUnicodeCategory(c) = unicodeCategories.[uc] then 
+                                    yield Inp(Alphabet(EncodeChar(c))) ])
+            CompileRegexp re dest
+
+        | Inp Any -> 
+            let re = Alt([ for n in GetAlphabet() do yield Inp(Alphabet(n)) ])
+            CompileRegexp re dest
+
+        | Inp (NotCharSet chars) -> 
+            let re = Alt [ // Include any characters from those in the alphabet besides those that are not immediately excluded
+                           for c in GetSingleCharAlphabet() do 
+                               let ec = EncodeChar c
+                               if not (chars.Contains(ec)) then 
+                                   yield Inp(Alphabet(ec))
+
+                           // Include all unicode categories 
+                           // That is, negations _only_ exclude precisely the given set of characters. You can't
+                           // exclude whole classes of characters as yet
+                           if !unicode then 
+                               let ucs = chars |> Set.map(DecodeChar >> System.Char.GetUnicodeCategory)  
+                               for KeyValue(nm,uc) in unicodeCategories do
+                                   //if ucs.Contains(uc) then 
+                                   //    do printfn "warning: the unicode category '\\%s' ('%s') is automatically excluded by this character set negation. Consider adding this to the negation." nm  (uc.ToString())
+                                   //    yield! []
+                                   //else
+                                       yield Inp(Alphabet(EncodeUnicodeCategory nm)) 
+                         ]
+            CompileRegexp re dest
+
+    let actions = new System.Collections.Generic.List<_>()
+    
+    /// Compile an acceptance of a regular expression into the NFA
+    let sTrans macros nodeId (regexp,code) = 
+        let actionId = actions.Count
+        actions.Add(code)
+        let sAccept = nfaNodeMap.NewNfaNode([],[(nodeId,actionId)])
+        CompileRegexp regexp sAccept 
+
+    let trs = clauses |> List.mapi (fun n x -> (Epsilon,sTrans macros n x)) 
+    let nfaStartNode = nfaNodeMap.NewNfaNode(trs,[])
+    nfaStartNode,(actions |> Seq.readonly), nfaNodeMap
+
+// TODO: consider a better representation here.
+type internal NfaNodeIdSetBuilder = HashSet<NodeId>
+
+type internal NfaNodeIdSet(nodes: NfaNodeIdSetBuilder) = 
+    // BEWARE: the next line is performance critical
+    let s = nodes |> Seq.toArray |> (fun arr -> Array.sortInPlaceWith compare arr; arr) // 19
+
+    // These are all surprisingly slower:
+    //let s = nodes |> Seq.toArray |> Array.sort 
+    //let s = nodes |> Seq.toArray |> Array.sortWith compare // 76
+    //let s = nodes |> Seq.toArray |> (fun arr -> Array.sortInPlace arr; arr) // 76
+
+    member x.Representation = s
+    member x.Elements = s 
+    member x.Fold f z = Array.fold f z s
+    interface System.IComparable with 
+        member x.CompareTo(y:obj) = 
+            let y = (y :?> NfaNodeIdSet)
+            let xr = x.Representation
+            let yr = y.Representation
+            let c = compare xr.Length yr.Length
+            if c <> 0 then c else 
+            let n = yr.Length
+            let rec go i = 
+                if i >= n then 0 else
+                let c = compare xr.[i] yr.[i]
+                if c <> 0 then c else
+                go (i+1) 
+            go 0
+
+    override x.Equals(y:obj) = 
+        match y with 
+        | :? NfaNodeIdSet as y -> 
+            let xr = x.Representation
+            let yr = y.Representation
+            let n = yr.Length
+            xr.Length = n && 
+            (let rec go i = (i < n) && xr.[i] = yr.[i] && go (i+1) 
+             go 0)
+        | _ -> false
+
+    override x.GetHashCode() = hash s
+
+    member x.IsEmpty = (s.Length = 0)
+    member x.Iterate f = s |> Array.iter f
+
+type NodeSetSet = Set<NfaNodeIdSet>
+
+let newDfaNodeId = 
+    let i = ref 0 
+    fun () -> let res = !i in incr i; res
+   
+let NfaToDfa (nfaNodeMap:NfaNodeMap) nfaStartNode = 
+    let numNfaNodes = nfaNodeMap.Count
+    let rec EClosure1 (acc:NfaNodeIdSetBuilder) (n:NfaNode) = 
+        if not (acc.Contains(n.Id)) then 
+            acc.Add(n.Id) |> ignore;
+            if n.Transitions.ContainsKey(Epsilon) then
+                match n.Transitions.[Epsilon] with 
+                | [] -> () // this Clause is an optimization - the list is normally empty
+                | tr -> 
+                    //printfn "n.Id = %A, #Epsilon = %d" n.Id tr.Length
+                    tr |> List.iter (EClosure1 acc) 
+
+    let EClosure (moves:list<NodeId>) = 
+        let acc = new NfaNodeIdSetBuilder(HashIdentity.Structural)
+        for i in moves do
+            EClosure1 acc nfaNodeMap.[i];
+        new NfaNodeIdSet(acc)
+
+    // Compute all the immediate one-step moves for a set of NFA states, as a dictionary
+    // mapping inputs to destination lists
+    let ComputeMoves (nset:NfaNodeIdSet) = 
+        let moves = new MultiMap<_,_>()
+        nset.Iterate(fun nodeId -> 
+            for (KeyValue(inp,dests)) in nfaNodeMap.[nodeId].Transitions do
+                if inp <> Epsilon then 
+                    match dests with 
+                    | [] -> ()  // this Clause is an optimization - the list is normally empty
+                    | tr -> tr |> List.iter(fun dest -> AddToMultiMap moves inp dest.Id))
+        moves
+
+    let acc = new NfaNodeIdSetBuilder(HashIdentity.Structural)
+    EClosure1 acc nfaStartNode;
+    let nfaSet0 = new NfaNodeIdSet(acc)
+
+    let dfaNodes = ref (Map.empty<NfaNodeIdSet,DfaNode>)
+
+    let GetDfaNode nfaSet = 
+        if (!dfaNodes).ContainsKey(nfaSet) then 
+            (!dfaNodes).[nfaSet]
+        else 
+            let dfaNode =
+                { Id= newDfaNodeId(); 
+                  Name = nfaSet.Fold (fun s nid -> nfaNodeMap.[nid].Name+"-"+s) ""; 
+                  Transitions=[];
+                  Accepted= nfaSet.Elements 
+                            |> Seq.map (fun nid -> nfaNodeMap.[nid].Accepted)
+                            |> List.concat }
+            //Printf.printfn "id = %d" dfaNode.Id;
+
+            dfaNodes := (!dfaNodes).Add(nfaSet,dfaNode); 
+            dfaNode
+            
+    let workList = ref [nfaSet0]
+    let doneSet = ref Set.empty
+
+    //let count = ref 0 
+    let rec Loop () = 
+        match !workList with 
+        | [] -> ()
+        | nfaSet ::t -> 
+            workList := t;
+            if (!doneSet).Contains(nfaSet) then 
+                Loop () 
+            else
+                let moves = ComputeMoves nfaSet
+                for (KeyValue(inp,movesForInput)) in moves do
+                    assert (inp <> Epsilon);
+                    let moveSet = EClosure movesForInput;
+                    if not moveSet.IsEmpty then 
+                        //incr count
+                        let dfaNode = GetDfaNode nfaSet
+                        dfaNode.Transitions <- (inp, GetDfaNode moveSet) :: dfaNode.Transitions;
+                        (* Printf.printf "%d (%s) : %s --> %d (%s)\n" dfaNode.Id dfaNode.Name (match inp with EncodeChar c -> String.make 1 c | LEof -> "eof") moveSetDfaNode.Id moveSetDfaNode.Name;*)
+                        workList := moveSet :: !workList;
+
+                doneSet := (!doneSet).Add(nfaSet);
+
+
+                Loop()
+    Loop();
+    //Printf.printfn "count = %d" !count;
+    let ruleStartNode = GetDfaNode nfaSet0
+    let ruleNodes = 
+        (!dfaNodes) 
+        |> Seq.map (fun kvp -> kvp.Value) 
+        |> Seq.toList
+        |> List.sortBy (fun s -> s.Id)
+    ruleStartNode,ruleNodes
+
+let Compile spec = 
+    List.foldBack
+        (fun (name,args,clauses) (perRuleData,dfaNodes) -> 
+            let nfa, actions, nfaNodeMap = LexerStateToNfa (Map.ofList spec.Macros) clauses
+            let ruleStartNode, ruleNodes = NfaToDfa nfaNodeMap nfa
+            //Printf.printfn "name = %s, ruleStartNode = %O" name ruleStartNode.Id;
+            (ruleStartNode,actions) :: perRuleData, ruleNodes @ dfaNodes)
+        spec.Rules
+        ([],[])
+
--- fsharp-3.1.1.26+dfsg2.orig/FsLex/fslexlex.fsl
+++ fsharp-3.1.1.26+dfsg2/FsLex/fslexlex.fsl
@@ -1,208 +1,208 @@
-{
-(* (c) Microsoft Corporation 2005-2008.  *)
-  
-module internal FSharp.PowerPack.FsLex.Lexer
-  
-open FSharp.PowerPack.FsLex.AST
-open FSharp.PowerPack.FsLex.Parser
-open Internal.Utilities
-open Internal.Utilities.Text.Lexing
-open System.Text
-
-let escape c = 
-  match c with
-  | '\\' -> '\\'
-  | '\'' -> '\''
-  | 'n' -> '\n'
-  | 't' -> '\t'
-  | 'b' -> '\b'
-  | 'r' -> '\r'
-  | c -> c
-
-let lexeme (lexbuf : LexBuffer<char>) = new System.String(lexbuf.Lexeme)
-let newline (lexbuf:LexBuffer<_>) = lexbuf.EndPos <- lexbuf.EndPos.NextLine
-
-let unexpected_char lexbuf =
-      failwith ("Unexpected character '"+(lexeme lexbuf)+"'")
-
-let digit d = 
-      if d >= '0' && d <= '9' then int32 d - int32 '0'   
-      else failwith "digit" 
-
-let hexdigit d = 
-      if d >= '0' && d <= '9' then digit d 
-      else if d >= 'a' && d <= 'f' then int32 d - int32 'a' + 10
-      else if d >= 'A' && d <= 'F' then int32 d - int32 'A' + 10
-      else failwithf "bad hexdigit: %c" d 
-
-let trigraph c1 c2 c3 =
-      char (digit c1 * 100 + digit c2 * 10 + digit c3)
-
-let hexgraph c1 c2 =
-      char (hexdigit c1 * 16 + hexdigit c2)
-
-let unicodegraph_short (s:string) =
-    if s.Length <> 4 then failwith "unicodegraph";
-    char(hexdigit s.[0] * 4096 + hexdigit s.[1] * 256 + hexdigit s.[2] * 16 + hexdigit s.[3])
-
-let unicodegraph_long (s:string) =
-    if s.Length <> 8 then failwith "unicodegraph_long";
-    let high = hexdigit s.[0] * 4096 + hexdigit s.[1] * 256 + hexdigit s.[2] * 16 + hexdigit s.[3] in 
-    let low = hexdigit s.[4] * 4096 + hexdigit s.[5] * 256 + hexdigit s.[6] * 16 + hexdigit s.[7] in 
-    if high = 0 then None, char low 
-    else 
-      (* A surrogate pair - see http://www.unicode.org/unicode/uni2book/ch03.pdf, section 3.7 *)
-      Some (char(0xD800 + ((high * 0x10000 + low - 0x10000) / 0x400))),
-      char(0xDF30 + ((high * 0x10000 + low - 0x10000) % 0x400))
-
-} 
-
-let letter = ['A'-'Z'] | ['a'-'z']
-let digit = ['0'-'9']
-let whitespace = [' ' '\t']
-let char = '\'' ( [^'\\'] | ('\\' ( '\\' | '\'' | "\"" | 'n' | 't' | 'b' | 'r'))) '\''
-let hex = ['0'-'9'] | ['A'-'F'] | ['a'-'f']
-let hexgraph = '\\' 'x' hex hex
-let trigraph = '\\' digit digit digit
-let newline = ('\n' | '\r' '\n')
-let ident_start_char = letter       
-let ident_char = ( ident_start_char| digit | ['\'' '_'] )
-let ident = ident_start_char ident_char*
-
-let unicodegraph_short = '\\' 'u' hex hex hex hex
-let unicodegraph_long =  '\\' 'U' hex hex hex hex hex hex hex hex
-
-rule token = parse
- | "rule" {RULE }
- | "parse" {PARSE }
- | "eof" {EOF }
- | "let" {LET }
- | "and" {AND }
- | char
-   { let s = lexeme lexbuf in 
-     CHAR (if s.[1] = '\\' then escape s.[2] else s.[1])  }
- 
- | '\'' trigraph '\''
-   { let s = lexeme lexbuf in 
-     CHAR (trigraph s.[2] s.[3] s.[4]) }
- 
- | '\'' hexgraph '\''
-   { let s = lexeme lexbuf in 
-     CHAR (hexgraph s.[3] s.[4]) }
- 
- | '\'' unicodegraph_short '\''
-   { let s = lexeme lexbuf in 
-     CHAR (unicodegraph_short s.[3..6]) }
- 
- | '\'' unicodegraph_long '\''
-   { let s = lexeme lexbuf in 
-     match (unicodegraph_long s.[3..10]) with 
-     | None, c -> CHAR(c)
-     | Some _ , _ -> failwith "Unicode characters needing surrogate pairs are not yet supported by this tool" }
- 
- | '\'' '\\' ['A'-'Z'] ['a'-'z'] '\''
-   { let s = (lexeme lexbuf).[2..3] in 
-     UNICODE_CATEGORY (s) }
-     
- | '{' { let p = lexbuf.StartPos in 
-         let buff = (new StringBuilder 100) in
-         // adjust the first line to get even indentation for all lines w.r.t. the left hand margin
-         buff.Append (String.replicate (lexbuf.StartPos.Column+1) " ") |> ignore;
-         code p buff lexbuf }
-
- | '"' { string  lexbuf.StartPos (new StringBuilder 100) lexbuf }
- 
- | whitespace+  { token lexbuf }
- | newline { newline lexbuf; token lexbuf }
- | ident_start_char ident_char* { IDENT (lexeme lexbuf) }
- | '|' { BAR }
- | '.' { DOT }
- | '+' { PLUS }
- | '*' { STAR }
- | '?' { QMARK }
- | '=' { EQUALS }
- | '[' { LBRACK }
- | ']' { RBRACK }
- | '(' { LPAREN }
- | ')' { RPAREN }
- | '_' { UNDERSCORE }
- | '^' { HAT }
- | '-' { DASH }
- | "(*" { ignore(comment lexbuf.StartPos lexbuf); token lexbuf }
- | "//" [^'\n''\r']* { token lexbuf }
- | _ { unexpected_char lexbuf }     
- | eof { EOF  }                                     
-and string p buff = parse
- |  '\\' newline { newline lexbuf; string p buff lexbuf }
- |  '\\' ( '"' | '\\' | '\'' | 'n' | 't' | 'b' | 'r')
-   { let _ = buff.Append (escape (lexeme lexbuf).[1]) in
-     string p buff lexbuf } 
- | trigraph
-   { let s = lexeme lexbuf in 
-     let _ = buff.Append (trigraph s.[1] s.[2] s.[3]) in
-     string p buff lexbuf  }
- | '"' { STRING (buff.ToString()) }
- | newline { newline lexbuf; 
-             let _ = buff.Append System.Environment.NewLine in
-             string p buff lexbuf }
- | (whitespace | letter | digit) +  
-   { let _ = buff.Append (lexeme lexbuf) in 
-     string p buff lexbuf }
- | eof { failwith (Printf.sprintf "end of file in string started at (%d,%d)" p.pos_lnum (p.pos_cnum - p.pos_bol))  }
- | _ { let _ = buff.Append (lexeme lexbuf).[0] in
-       string p buff lexbuf }
-and code p buff = parse
- | "}" { CODE (buff.ToString(), p) }
- | "{" { let _ = buff.Append (lexeme lexbuf) in 
-         ignore(code p buff lexbuf); 
-         let _ = buff.Append "}" in
-         code p buff lexbuf }
- | '\\' ('"' | '\\')
-   { let _ = buff.Append (lexeme lexbuf) in 
-     code p buff lexbuf } 
- | "\"" { let _ = buff.Append (lexeme lexbuf) in 
-          ignore(codestring buff lexbuf); 
-          code p buff lexbuf }
- | newline { newline lexbuf; 
-             let _ = buff.Append System.Environment.NewLine in
-             code p buff lexbuf }
- | (whitespace | letter | digit) +  
-   { let _ = buff.Append (lexeme lexbuf) in 
-     code p buff lexbuf }
- | "//" [^'\n''\r']*
-   { let _ = buff.Append (lexeme lexbuf) in
-     code p buff lexbuf }
- | eof { EOF }
- | _ { let _ = buff.Append (lexeme lexbuf).[0] in
-       code p buff lexbuf }
-
-and codestring buff = parse
- |  '\\' ('"' | '\\')
-   { let _ = buff.Append (lexeme lexbuf) in 
-     codestring buff lexbuf } 
- | '"' { let _ = buff.Append (lexeme lexbuf) in 
-         buff.ToString() }
- | newline { newline lexbuf; 
-             let _ = buff.Append System.Environment.NewLine in
-             codestring buff lexbuf }
- | (whitespace | letter | digit) +  
-   { let _ = buff.Append (lexeme lexbuf) in 
-     codestring buff lexbuf }
- | eof { failwith "unterminated string in code" }
- | _ { let _ = buff.Append (lexeme lexbuf).[0] in
-       codestring buff lexbuf }
-
-and comment p = parse
- |  char { comment p lexbuf } 
- | '"' { ignore(try string lexbuf.StartPos (new StringBuilder 100) lexbuf 
-                with Failure s -> failwith (s + "\n" + Printf.sprintf "error while processing string nested in comment started at (%d,%d)" p.pos_lnum (p.pos_cnum - p.pos_bol))); 
-         comment p lexbuf }
- | "(*" { ignore(try comment p lexbuf with Failure s -> failwith (s + "\n" + Printf.sprintf "error while processing nested comment started at (%d,%d)" p.pos_lnum (p.pos_cnum - p.pos_bol))); 
-          comment p lexbuf }
- | newline { newline lexbuf; comment p lexbuf }
- | "*)" { () }
- | eof { failwith (Printf.sprintf "end of file in comment started at (%d,%d)" p.pos_lnum (p.pos_cnum - p.pos_bol))  }
- | [^ '\'' '(' '*' '\n' '\r' '"' ')' ]+  { comment p lexbuf }
- | _  { comment p lexbuf }
-
-               
+{
+(* (c) Microsoft Corporation 2005-2008.  *)
+  
+module internal FSharp.PowerPack.FsLex.Lexer
+  
+open FSharp.PowerPack.FsLex.AST
+open FSharp.PowerPack.FsLex.Parser
+open Internal.Utilities
+open Internal.Utilities.Text.Lexing
+open System.Text
+
+let escape c = 
+  match c with
+  | '\\' -> '\\'
+  | '\'' -> '\''
+  | 'n' -> '\n'
+  | 't' -> '\t'
+  | 'b' -> '\b'
+  | 'r' -> '\r'
+  | c -> c
+
+let lexeme (lexbuf : LexBuffer<char>) = new System.String(lexbuf.Lexeme)
+let newline (lexbuf:LexBuffer<_>) = lexbuf.EndPos <- lexbuf.EndPos.NextLine
+
+let unexpected_char lexbuf =
+      failwith ("Unexpected character '"+(lexeme lexbuf)+"'")
+
+let digit d = 
+      if d >= '0' && d <= '9' then int32 d - int32 '0'   
+      else failwith "digit" 
+
+let hexdigit d = 
+      if d >= '0' && d <= '9' then digit d 
+      else if d >= 'a' && d <= 'f' then int32 d - int32 'a' + 10
+      else if d >= 'A' && d <= 'F' then int32 d - int32 'A' + 10
+      else failwithf "bad hexdigit: %c" d 
+
+let trigraph c1 c2 c3 =
+      char (digit c1 * 100 + digit c2 * 10 + digit c3)
+
+let hexgraph c1 c2 =
+      char (hexdigit c1 * 16 + hexdigit c2)
+
+let unicodegraph_short (s:string) =
+    if s.Length <> 4 then failwith "unicodegraph";
+    char(hexdigit s.[0] * 4096 + hexdigit s.[1] * 256 + hexdigit s.[2] * 16 + hexdigit s.[3])
+
+let unicodegraph_long (s:string) =
+    if s.Length <> 8 then failwith "unicodegraph_long";
+    let high = hexdigit s.[0] * 4096 + hexdigit s.[1] * 256 + hexdigit s.[2] * 16 + hexdigit s.[3] in 
+    let low = hexdigit s.[4] * 4096 + hexdigit s.[5] * 256 + hexdigit s.[6] * 16 + hexdigit s.[7] in 
+    if high = 0 then None, char low 
+    else 
+      (* A surrogate pair - see http://www.unicode.org/unicode/uni2book/ch03.pdf, section 3.7 *)
+      Some (char(0xD800 + ((high * 0x10000 + low - 0x10000) / 0x400))),
+      char(0xDF30 + ((high * 0x10000 + low - 0x10000) % 0x400))
+
+} 
+
+let letter = ['A'-'Z'] | ['a'-'z']
+let digit = ['0'-'9']
+let whitespace = [' ' '\t']
+let char = '\'' ( [^'\\'] | ('\\' ( '\\' | '\'' | "\"" | 'n' | 't' | 'b' | 'r'))) '\''
+let hex = ['0'-'9'] | ['A'-'F'] | ['a'-'f']
+let hexgraph = '\\' 'x' hex hex
+let trigraph = '\\' digit digit digit
+let newline = ('\n' | '\r' '\n')
+let ident_start_char = letter       
+let ident_char = ( ident_start_char| digit | ['\'' '_'] )
+let ident = ident_start_char ident_char*
+
+let unicodegraph_short = '\\' 'u' hex hex hex hex
+let unicodegraph_long =  '\\' 'U' hex hex hex hex hex hex hex hex
+
+rule token = parse
+ | "rule" {RULE }
+ | "parse" {PARSE }
+ | "eof" {EOF }
+ | "let" {LET }
+ | "and" {AND }
+ | char
+   { let s = lexeme lexbuf in 
+     CHAR (if s.[1] = '\\' then escape s.[2] else s.[1])  }
+ 
+ | '\'' trigraph '\''
+   { let s = lexeme lexbuf in 
+     CHAR (trigraph s.[2] s.[3] s.[4]) }
+ 
+ | '\'' hexgraph '\''
+   { let s = lexeme lexbuf in 
+     CHAR (hexgraph s.[3] s.[4]) }
+ 
+ | '\'' unicodegraph_short '\''
+   { let s = lexeme lexbuf in 
+     CHAR (unicodegraph_short s.[3..6]) }
+ 
+ | '\'' unicodegraph_long '\''
+   { let s = lexeme lexbuf in 
+     match (unicodegraph_long s.[3..10]) with 
+     | None, c -> CHAR(c)
+     | Some _ , _ -> failwith "Unicode characters needing surrogate pairs are not yet supported by this tool" }
+ 
+ | '\'' '\\' ['A'-'Z'] ['a'-'z'] '\''
+   { let s = (lexeme lexbuf).[2..3] in 
+     UNICODE_CATEGORY (s) }
+     
+ | '{' { let p = lexbuf.StartPos in 
+         let buff = (new StringBuilder 100) in
+         // adjust the first line to get even indentation for all lines w.r.t. the left hand margin
+         buff.Append (String.replicate (lexbuf.StartPos.Column+1) " ") |> ignore;
+         code p buff lexbuf }
+
+ | '"' { string  lexbuf.StartPos (new StringBuilder 100) lexbuf }
+ 
+ | whitespace+  { token lexbuf }
+ | newline { newline lexbuf; token lexbuf }
+ | ident_start_char ident_char* { IDENT (lexeme lexbuf) }
+ | '|' { BAR }
+ | '.' { DOT }
+ | '+' { PLUS }
+ | '*' { STAR }
+ | '?' { QMARK }
+ | '=' { EQUALS }
+ | '[' { LBRACK }
+ | ']' { RBRACK }
+ | '(' { LPAREN }
+ | ')' { RPAREN }
+ | '_' { UNDERSCORE }
+ | '^' { HAT }
+ | '-' { DASH }
+ | "(*" { ignore(comment lexbuf.StartPos lexbuf); token lexbuf }
+ | "//" [^'\n''\r']* { token lexbuf }
+ | _ { unexpected_char lexbuf }     
+ | eof { EOF  }                                     
+and string p buff = parse
+ |  '\\' newline { newline lexbuf; string p buff lexbuf }
+ |  '\\' ( '"' | '\\' | '\'' | 'n' | 't' | 'b' | 'r')
+   { let _ = buff.Append (escape (lexeme lexbuf).[1]) in
+     string p buff lexbuf } 
+ | trigraph
+   { let s = lexeme lexbuf in 
+     let _ = buff.Append (trigraph s.[1] s.[2] s.[3]) in
+     string p buff lexbuf  }
+ | '"' { STRING (buff.ToString()) }
+ | newline { newline lexbuf; 
+             let _ = buff.Append System.Environment.NewLine in
+             string p buff lexbuf }
+ | (whitespace | letter | digit) +  
+   { let _ = buff.Append (lexeme lexbuf) in 
+     string p buff lexbuf }
+ | eof { failwith (Printf.sprintf "end of file in string started at (%d,%d)" p.pos_lnum (p.pos_cnum - p.pos_bol))  }
+ | _ { let _ = buff.Append (lexeme lexbuf).[0] in
+       string p buff lexbuf }
+and code p buff = parse
+ | "}" { CODE (buff.ToString(), p) }
+ | "{" { let _ = buff.Append (lexeme lexbuf) in 
+         ignore(code p buff lexbuf); 
+         let _ = buff.Append "}" in
+         code p buff lexbuf }
+ | '\\' ('"' | '\\')
+   { let _ = buff.Append (lexeme lexbuf) in 
+     code p buff lexbuf } 
+ | "\"" { let _ = buff.Append (lexeme lexbuf) in 
+          ignore(codestring buff lexbuf); 
+          code p buff lexbuf }
+ | newline { newline lexbuf; 
+             let _ = buff.Append System.Environment.NewLine in
+             code p buff lexbuf }
+ | (whitespace | letter | digit) +  
+   { let _ = buff.Append (lexeme lexbuf) in 
+     code p buff lexbuf }
+ | "//" [^'\n''\r']*
+   { let _ = buff.Append (lexeme lexbuf) in
+     code p buff lexbuf }
+ | eof { EOF }
+ | _ { let _ = buff.Append (lexeme lexbuf).[0] in
+       code p buff lexbuf }
+
+and codestring buff = parse
+ |  '\\' ('"' | '\\')
+   { let _ = buff.Append (lexeme lexbuf) in 
+     codestring buff lexbuf } 
+ | '"' { let _ = buff.Append (lexeme lexbuf) in 
+         buff.ToString() }
+ | newline { newline lexbuf; 
+             let _ = buff.Append System.Environment.NewLine in
+             codestring buff lexbuf }
+ | (whitespace | letter | digit) +  
+   { let _ = buff.Append (lexeme lexbuf) in 
+     codestring buff lexbuf }
+ | eof { failwith "unterminated string in code" }
+ | _ { let _ = buff.Append (lexeme lexbuf).[0] in
+       codestring buff lexbuf }
+
+and comment p = parse
+ |  char { comment p lexbuf } 
+ | '"' { ignore(try string lexbuf.StartPos (new StringBuilder 100) lexbuf 
+                with Failure s -> failwith (s + "\n" + Printf.sprintf "error while processing string nested in comment started at (%d,%d)" p.pos_lnum (p.pos_cnum - p.pos_bol))); 
+         comment p lexbuf }
+ | "(*" { ignore(try comment p lexbuf with Failure s -> failwith (s + "\n" + Printf.sprintf "error while processing nested comment started at (%d,%d)" p.pos_lnum (p.pos_cnum - p.pos_bol))); 
+          comment p lexbuf }
+ | newline { newline lexbuf; comment p lexbuf }
+ | "*)" { () }
+ | eof { failwith (Printf.sprintf "end of file in comment started at (%d,%d)" p.pos_lnum (p.pos_cnum - p.pos_bol))  }
+ | [^ '\'' '(' '*' '\n' '\r' '"' ')' ]+  { comment p lexbuf }
+ | _  { comment p lexbuf }
+
+               
--- fsharp-3.1.1.26+dfsg2.orig/FsLex/fslexpars.fsy
+++ fsharp-3.1.1.26+dfsg2/FsLex/fslexpars.fsy
@@ -1,55 +1,55 @@
-%{
-(* (c) Microsoft Corporation 2005-2008.  *)
-
-open FSharp.PowerPack.FsLex
-open FSharp.PowerPack.FsLex.AST
-
-%} 
-
-%type <AST.Spec> spec
-%token <string> STRING IDENT
-%token <AST.Code> CODE 
-%token <char> CHAR
-%token <string> UNICODE_CATEGORY
-%token RULE PARSE LET  AND LPAREN RPAREN
-%token EOF BAR DOT PLUS STAR QMARK EQUALS UNDERSCORE LBRACK RBRACK HAT DASH
-%start spec
-%left BAR
-%left regexp_alt
-%left regexp_seq
-%nonassoc regexp_opt
-%nonassoc regexp_plus regexp_star
-%%      
-
-spec: codeopt Macros RULE Rules codeopt { { TopCode=$1;Macros=$2;Rules=$4;BottomCode=$5 } }
-codeopt: CODE { $1 } | { "", (parseState.ResultRange |> fst) }
-Macros:  { [] } | macro Macros { $1 :: $2 }
-macro: LET IDENT EQUALS regexp { ($2, $4) }
-Rules: rule AND Rules { $1 :: $3 } | rule { [$1] }
-rule: IDENT args EQUALS PARSE optbar clauses { ($1,$2,$6) }
-args: { [] } | IDENT args { $1 :: $2 } 
-optbar: { } | BAR { }
-clauses: clause BAR clauses {$1 :: $3 } | clause { [$1] }
-clause: regexp CODE { $1, $2 }
-regexp: 
-| CHAR { Inp(Alphabet(EncodeChar $1)) }
-| UNICODE_CATEGORY { Inp(UnicodeCategory $1) }
-| EOF { Inp(Alphabet(Eof)) }
-| UNDERSCORE { Inp Any }
-| STRING { Seq([ for n in 0 .. $1.Length - 1 -> Inp(Alphabet(EncodeChar $1.[n]))]) }
-| IDENT { Macro($1) }
-| regexp regexp %prec regexp_seq  { Seq[$1;$2] }
-| regexp PLUS %prec regexp_plus  { Seq[$1;Star $1] }
-| regexp STAR %prec regexp_star  { Star $1 }
-| regexp QMARK %prec regexp_opt  { Alt[Seq[];$1] }
-| regexp BAR regexp %prec regexp_alt  { Alt[$1;$3] }
-| LPAREN regexp RPAREN  { $2 }
-| LBRACK charset RBRACK   { Alt [ for c in $2 -> Inp(Alphabet(c)) ] }
-| LBRACK HAT charset RBRACK   { Inp(NotCharSet($3)) }
-
-charset: 
- | CHAR { Set.singleton(EncodeChar $1) } 
- | CHAR DASH CHAR { Set.ofSeq [ for c in $1 .. $3 -> EncodeChar c ] }
- | charset charset { Set.union $1 $2  }
-
-
+%{
+(* (c) Microsoft Corporation 2005-2008.  *)
+
+open FSharp.PowerPack.FsLex
+open FSharp.PowerPack.FsLex.AST
+
+%} 
+
+%type <AST.Spec> spec
+%token <string> STRING IDENT
+%token <AST.Code> CODE 
+%token <char> CHAR
+%token <string> UNICODE_CATEGORY
+%token RULE PARSE LET  AND LPAREN RPAREN
+%token EOF BAR DOT PLUS STAR QMARK EQUALS UNDERSCORE LBRACK RBRACK HAT DASH
+%start spec
+%left BAR
+%left regexp_alt
+%left regexp_seq
+%nonassoc regexp_opt
+%nonassoc regexp_plus regexp_star
+%%      
+
+spec: codeopt Macros RULE Rules codeopt { { TopCode=$1;Macros=$2;Rules=$4;BottomCode=$5 } }
+codeopt: CODE { $1 } | { "", (parseState.ResultRange |> fst) }
+Macros:  { [] } | macro Macros { $1 :: $2 }
+macro: LET IDENT EQUALS regexp { ($2, $4) }
+Rules: rule AND Rules { $1 :: $3 } | rule { [$1] }
+rule: IDENT args EQUALS PARSE optbar clauses { ($1,$2,$6) }
+args: { [] } | IDENT args { $1 :: $2 } 
+optbar: { } | BAR { }
+clauses: clause BAR clauses {$1 :: $3 } | clause { [$1] }
+clause: regexp CODE { $1, $2 }
+regexp: 
+| CHAR { Inp(Alphabet(EncodeChar $1)) }
+| UNICODE_CATEGORY { Inp(UnicodeCategory $1) }
+| EOF { Inp(Alphabet(Eof)) }
+| UNDERSCORE { Inp Any }
+| STRING { Seq([ for n in 0 .. $1.Length - 1 -> Inp(Alphabet(EncodeChar $1.[n]))]) }
+| IDENT { Macro($1) }
+| regexp regexp %prec regexp_seq  { Seq[$1;$2] }
+| regexp PLUS %prec regexp_plus  { Seq[$1;Star $1] }
+| regexp STAR %prec regexp_star  { Star $1 }
+| regexp QMARK %prec regexp_opt  { Alt[Seq[];$1] }
+| regexp BAR regexp %prec regexp_alt  { Alt[$1;$3] }
+| LPAREN regexp RPAREN  { $2 }
+| LBRACK charset RBRACK   { Alt [ for c in $2 -> Inp(Alphabet(c)) ] }
+| LBRACK HAT charset RBRACK   { Inp(NotCharSet($3)) }
+
+charset: 
+ | CHAR { Set.singleton(EncodeChar $1) } 
+ | CHAR DASH CHAR { Set.ofSeq [ for c in $1 .. $3 -> EncodeChar c ] }
+ | charset charset { Set.union $1 $2  }
+
+
--- fsharp-3.1.1.26+dfsg2.orig/FsSrGen/Program.fs
+++ fsharp-3.1.1.26+dfsg2/FsSrGen/Program.fs
@@ -1,426 +1,426 @@
-namespace FSSRGen
-
-module Implementation =
-    let JustPrintErr(filename, line, msg) =
-        printfn "%s(%d): error : %s" filename line msg
-        
-    /// Err(filename, line, msg)
-    let Err(filename, line, msg) =
-        JustPrintErr(filename, line, msg)
-        printfn "Note that the syntax of each line is one of these three alternatives:"
-        printfn "# comment"
-        printfn "ident,\"string\""
-        printfn "errNum,ident,\"string\""
-        failwithf "there were errors in the file '%s'" filename
-
-    let xmlBoilerPlateString = @"<?xml version=""1.0"" encoding=""utf-8""?>
-    <root>
-      <!-- 
-        Microsoft ResX Schema 
-        
-        Version 2.0
-        
-        The primary goals of this format is to allow a simple XML format 
-        that is mostly human readable. The generation and parsing of the 
-        various data types are done through the TypeConverter classes 
-        associated with the data types.
-        
-        Example:
-        
-        ... ado.net/XML headers & schema ...
-        <resheader name=""resmimetype"">text/microsoft-resx</resheader>
-        <resheader name=""version"">2.0</resheader>
-        <resheader name=""reader"">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
-        <resheader name=""writer"">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
-        <data name=""Name1""><value>this is my long string</value><comment>this is a comment</comment></data>
-        <data name=""Color1"" type=""System.Drawing.Color, System.Drawing"">Blue</data>
-        <data name=""Bitmap1"" mimetype=""application/x-microsoft.net.object.binary.base64"">
-            <value>[base64 mime encoded serialized .NET Framework object]</value>
-        </data>
-        <data name=""Icon1"" type=""System.Drawing.Icon, System.Drawing"" mimetype=""application/x-microsoft.net.object.bytearray.base64"">
-            <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
-            <comment>This is a comment</comment>
-        </data>
-                    
-        There are any number of ""resheader"" rows that contain simple 
-        name/value pairs.
-        
-        Each data row contains a name, and value. The row also contains a 
-        type or mimetype. Type corresponds to a .NET class that support 
-        text/value conversion through the TypeConverter architecture. 
-        Classes that don't support this are serialized and stored with the 
-        mimetype set.
-        
-        The mimetype is used for serialized objects, and tells the 
-        ResXResourceReader how to depersist the object. This is currently not 
-        extensible. For a given mimetype the value must be set accordingly:
-        
-        Note - application/x-microsoft.net.object.binary.base64 is the format 
-        that the ResXResourceWriter will generate, however the reader can 
-        read any of the formats listed below.
-        
-        mimetype: application/x-microsoft.net.object.binary.base64
-        value   : The object must be serialized with 
-                : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
-                : and then encoded with base64 encoding.
-        
-        mimetype: application/x-microsoft.net.object.soap.base64
-        value   : The object must be serialized with 
-                : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
-                : and then encoded with base64 encoding.
-
-        mimetype: application/x-microsoft.net.object.bytearray.base64
-        value   : The object must be serialized into a byte array 
-                : using a System.ComponentModel.TypeConverter
-                : and then encoded with base64 encoding.
-        -->
-      <xsd:schema id=""root"" xmlns="""" xmlns:xsd=""http://www.w3.org/2001/XMLSchema"" xmlns:msdata=""urn:schemas-microsoft-com:xml-msdata"">
-        <xsd:import namespace=""http://www.w3.org/XML/1998/namespace"" />
-        <xsd:element name=""root"" msdata:IsDataSet=""true"">
-          <xsd:complexType>
-            <xsd:choice maxOccurs=""unbounded"">
-              <xsd:element name=""metadata"">
-                <xsd:complexType>
-                  <xsd:sequence>
-                    <xsd:element name=""value"" type=""xsd:string"" minOccurs=""0"" />
-                  </xsd:sequence>
-                  <xsd:attribute name=""name"" use=""required"" type=""xsd:string"" />
-                  <xsd:attribute name=""type"" type=""xsd:string"" />
-                  <xsd:attribute name=""mimetype"" type=""xsd:string"" />
-                  <xsd:attribute ref=""xml:space"" />
-                </xsd:complexType>
-              </xsd:element>
-              <xsd:element name=""assembly"">
-                <xsd:complexType>
-                  <xsd:attribute name=""alias"" type=""xsd:string"" />
-                  <xsd:attribute name=""name"" type=""xsd:string"" />
-                </xsd:complexType>
-              </xsd:element>
-              <xsd:element name=""data"">
-                <xsd:complexType>
-                  <xsd:sequence>
-                    <xsd:element name=""value"" type=""xsd:string"" minOccurs=""0"" msdata:Ordinal=""1"" />
-                    <xsd:element name=""comment"" type=""xsd:string"" minOccurs=""0"" msdata:Ordinal=""2"" />
-                  </xsd:sequence>
-                  <xsd:attribute name=""name"" type=""xsd:string"" use=""required"" msdata:Ordinal=""1"" />
-                  <xsd:attribute name=""type"" type=""xsd:string"" msdata:Ordinal=""3"" />
-                  <xsd:attribute name=""mimetype"" type=""xsd:string"" msdata:Ordinal=""4"" />
-                  <xsd:attribute ref=""xml:space"" />
-                </xsd:complexType>
-              </xsd:element>
-              <xsd:element name=""resheader"">
-                <xsd:complexType>
-                  <xsd:sequence>
-                    <xsd:element name=""value"" type=""xsd:string"" minOccurs=""0"" msdata:Ordinal=""1"" />
-                  </xsd:sequence>
-                  <xsd:attribute name=""name"" type=""xsd:string"" use=""required"" />
-                </xsd:complexType>
-              </xsd:element>
-            </xsd:choice>
-          </xsd:complexType>
-        </xsd:element>
-      </xsd:schema>
-      <resheader name=""resmimetype"">
-        <value>text/microsoft-resx</value>
-      </resheader>
-      <resheader name=""version"">
-        <value>2.0</value>
-      </resheader>
-      <resheader name=""reader"">
-        <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
-      </resheader>
-      <resheader name=""writer"">
-        <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
-      </resheader>
-    </root>"
-
-
-
-
-    // The kinds of 'holes' we can do
-    type HoleType =
-        | Int = 0     // %d
-        | String = 1  // %s
-        | Float = 2   // %f
-
-    let HoleTypeToString this =    
-        match this with
-        | HoleType.Int -> "System.Int32"
-        | HoleType.String -> "System.String"
-        | HoleType.Float -> "System.Double"
-        | _ -> failwith "impossible"
-        
-    let ComputeHoles filename lineNum (txt:string) : HoleType[] * string =
-        // takes in a %d%s kind of string, returns array of HoleType and {0}{1} kind of string
-        let mutable i = 0
-        let holeNumber = ref 0
-        let holes = ref []  // reverse order
-        let sb = new System.Text.StringBuilder()
-        let AddHole holeType =
-            sb.Append(sprintf "{%d}" !holeNumber) |> ignore
-            holeNumber := !holeNumber + 1
-            holes := holeType :: !holes
-        while i < txt.Length do
-            if txt.[i] = '%' then
-                if i+1 = txt.Length then
-                    Err(filename, lineNum, "(at end of string) % must be followed by d, f, s, or %")
-                else
-                    match txt.[i+1] with
-                    | 'd' -> AddHole HoleType.Int
-                    | 'f' -> AddHole HoleType.Float
-                    | 's' -> AddHole HoleType.String
-                    | '%' -> sb.Append('%') |> ignore
-                    | c -> Err(filename, lineNum, sprintf "'%%%c' is not a valid sequence, only %%d %%f %%s or %%%%" c)
-                i <- i + 2
-            else
-                match txt.[i] with
-                | '{' -> sb.Append("{{") |> ignore
-                | '}' -> sb.Append("}}") |> ignore
-                | c -> sb.Append(c) |> ignore
-                i <- i + 1
-        (!holes |> List.rev |> List.toArray, sb.ToString())
-
-    let Unquote (s : string) =
-        if s.StartsWith("\"") && s.EndsWith("\"") then s.Substring(1, s.Length - 2)
-        else failwith "error message string should be quoted"
-
-    let ParseLine filename lineNum (txt:string) =
-        let mutable errNum = None
-        let identB = new System.Text.StringBuilder()
-        let mutable i = 0
-        // parse optional error number
-        if i < txt.Length && System.Char.IsDigit(txt.[i]) then
-            let numB = new System.Text.StringBuilder()
-            while i < txt.Length && System.Char.IsDigit(txt.[i]) do
-                numB.Append(txt.[i]) |> ignore
-                i <- i + 1
-            errNum <- Some(int (numB.ToString()))
-            if i = txt.Length || not(txt.[i] = ',') then
-                Err(filename, lineNum, sprintf "After the error number '%d' there should be a comma" errNum.Value)
-            // Skip the comma
-            i <- i + 1
-        // parse short identifier
-        if i < txt.Length && not(System.Char.IsLetter(txt.[i])) then
-            Err(filename, lineNum, sprintf "The first character in the short identifier should be a letter, but found '%c'" txt.[i])
-        while i < txt.Length && System.Char.IsLetterOrDigit(txt.[i]) do
-            identB.Append(txt.[i]) |> ignore
-            i <- i + 1
-        let ident = identB.ToString()
-        if ident.Length = 0 then
-            Err(filename, lineNum, "Did not find the short identifier")
-        else
-            if i = txt.Length || not(txt.[i] = ',') then
-                Err(filename, lineNum, sprintf "After the identifier '%s' there should be a comma" ident)
-            else
-                // Skip the comma
-                i <- i + 1
-                if i = txt.Length then
-                    Err(filename, lineNum, sprintf "After the identifier '%s' and comma, there should be the quoted string resource" ident)
-                else
-                    let str = 
-                        try
-                            System.String.Format(Unquote(txt.Substring(i)))  // Format turns e.g '\n' into that char, but also requires that we 'escape' curlies in the original .txt file, e.g. "{{"
-                        with 
-                            e -> Err(filename, lineNum, sprintf "Error calling System.String.Format (note that curly braces must be escaped, and there cannot be trailing space on the line): >>>%s<<< -- %s" (txt.Substring(i)) e.Message)
-                    let holes, netFormatString = ComputeHoles filename lineNum str
-                    (lineNum, (errNum,ident), str, holes, netFormatString)
-
-    let stringBoilerPlatePrefix = @"            
-open Microsoft.FSharp.Core.LanguagePrimitives.IntrinsicOperators
-open Microsoft.FSharp.Reflection
-open System.Reflection
-// (namespaces below for specific case of using the tool to compile FSharp.Core itself)
-open Microsoft.FSharp.Core
-open Microsoft.FSharp.Core.Operators
-open Microsoft.FSharp.Text
-open Microsoft.FSharp.Collections
-open Printf
-"
-    let StringBoilerPlate filename = @"            
-    // BEGIN BOILERPLATE        
-    static let resources = lazy (new System.Resources.ResourceManager(""" + filename + @""", System.Reflection.Assembly.GetExecutingAssembly()))
-
-    static let GetString(name:string) =        
-        let s = resources.Value.GetString(name, System.Globalization.CultureInfo.CurrentUICulture)
-#if DEBUG
-        if null = s then
-            System.Diagnostics.Debug.Assert(false, sprintf ""**RESOURCE ERROR**: Resource token %s does not exist!"" name)
-#endif
-        s
-
-    static let mkFunctionValue (tys: System.Type[]) (impl:obj->obj) = 
-        FSharpValue.MakeFunction(FSharpType.MakeFunctionType(tys.[0],tys.[1]), impl)
-        
-    static let funTyC = typeof<(obj -> obj)>.GetGenericTypeDefinition()  
-
-    static let isNamedType(ty:System.Type) = not (ty.IsArray ||  ty.IsByRef ||  ty.IsPointer)
-    static let isFunctionType (ty1:System.Type)  = 
-        isNamedType(ty1) && ty1.IsGenericType && (ty1.GetGenericTypeDefinition()).Equals(funTyC)
-
-    static let rec destFunTy (ty:System.Type) =
-        if isFunctionType ty then 
-            ty, ty.GetGenericArguments() 
-        else
-            match ty.BaseType with 
-            | null -> failwith ""destFunTy: not a function type"" 
-            | b -> destFunTy b 
-
-    static let buildFunctionForOneArgPat (ty: System.Type) impl = 
-        let _,tys = destFunTy ty 
-        let rty = tys.[1]
-        // PERF: this technique is a bit slow (e.g. in simple cases, like 'sprintf ""%x""') 
-        mkFunctionValue tys (fun inp -> impl rty inp)
-                
-    static let capture1 (fmt:string) i args ty (go : obj list -> System.Type -> int -> obj) : obj = 
-        match fmt.[i] with
-        | '%' -> go args ty (i+1) 
-        | 'd'
-        | 'f'
-        | 's' -> buildFunctionForOneArgPat ty (fun rty n -> go (n::args) rty (i+1))
-        | _ -> failwith ""bad format specifier""
-        
-    // newlines and tabs get converted to strings when read from a resource file
-    // this will preserve their original intention    
-    static let postProcessString (s : string) =
-        s.Replace(""\\n"",""\n"").Replace(""\\t"",""\t"").Replace(""\\r"",""\r"").Replace(""\\\"""", ""\"""")
-        
-    static let createMessageString (messageString : string) (fmt : Printf.StringFormat<'T>) : 'T = 
-        let fmt = fmt.Value // here, we use the actual error string, as opposed to the one stored as fmt
-        let len = fmt.Length 
-
-        /// Function to capture the arguments and then run.
-        let rec capture args ty i = 
-            if i >= len ||  (fmt.[i] = '%' && i+1 >= len) then 
-                let b = new System.Text.StringBuilder()    
-                b.AppendFormat(messageString, [| for x in List.rev args -> x |]) |> ignore
-                box(b.ToString())
-            // REVIEW: For these purposes, this should be a nop, but I'm leaving it
-            // in incase we ever decide to support labels for the error format string
-            // E.g., ""<name>%s<foo>%d""
-            elif System.Char.IsSurrogatePair(fmt,i) then 
-               capture args ty (i+2)
-            else
-                match fmt.[i] with
-                | '%' ->
-                    let i = i+1 
-                    capture1 fmt i args ty capture
-                | _ ->
-                    capture args ty (i+1) 
-
-        (unbox (capture [] (typeof<'T>) 0) : 'T)
-
-    static let mutable swallowResourceText = false
-    
-    static let GetStringFunc((messageID : string),(fmt : Printf.StringFormat<'T>)) : 'T =
-        if swallowResourceText then
-            sprintf fmt
-        else
-            let mutable messageString = GetString(messageID)
-            messageString <- postProcessString messageString                            
-            createMessageString messageString fmt
-        
-    /// If set to true, then all error messages will just return the filled 'holes' delimited by ',,,'s - this is for language-neutral testing (e.g. localization-invariant baselines).
-    static member SwallowResourceText with get () = swallowResourceText
-                                      and set (b) = swallowResourceText <- b
-    // END BOILERPLATE        
-    "            
-
-    let RunMain(args:string array) =
-        let filename = System.IO.Path.GetFullPath(args.[0])  // TODO args validation
-        let outFilename = System.IO.Path.GetFullPath(args.[1])  // TODO args validation
-        let outXmlFilename = System.IO.Path.GetFullPath(args.[2])  // TODO args validation
-        try
-            let justfilename = System.IO.Path.GetFileNameWithoutExtension(filename)
-            if justfilename |> Seq.exists (fun c -> not(System.Char.IsLetterOrDigit(c))) then
-                Err(filename, 0, sprintf "The filename '%s' is not allowed; only letters and digits can be used, as the filename also becomes the namespace for the SR class" justfilename)
-
-            let lines = System.IO.File.ReadAllLines(filename) 
-                        |> Array.mapi (fun i s -> i,s) // keep line numbers
-                        |> Array.filter (fun (i,s) -> not(s.StartsWith("#")))  // filter out comments
-            let stringInfos = lines |> Array.map (fun (i,s) -> ParseLine filename i s)
-            // now we have array of (lineNum, ident, str, holes, netFormatString)  // str has %d, netFormatString has {0}
-            
-            // validate that all the idents are unique
-            let allIdents = new System.Collections.Generic.Dictionary<string,int>()
-            for (line,(_,ident),_,_,_) in stringInfos do
-                if allIdents.ContainsKey(ident) then
-                    Err(filename,line,sprintf "Identifier '%s' is already used previously on line %d - each identifier must be unique" ident allIdents.[ident])
-                allIdents.Add(ident,line)
-            
-            // validate that all the strings themselves are unique
-            let allStrs = new System.Collections.Generic.Dictionary<string,(int*string)>()
-            for (line,(_,ident),str,_,_) in stringInfos do
-                if allStrs.ContainsKey(str) then
-                    let prevLine,prevIdent = allStrs.[str]
-                    Err(filename,line,sprintf "String '%s' already appears on line %d with identifier '%s' - each string must be unique" str prevLine prevIdent)
-                allStrs.Add(str,(line,ident))
-            
-            use out = new System.IO.StreamWriter(outFilename)
-            fprintfn out "// This is a generated file; the original input is '%s'" filename
-            fprintfn out "namespace %s" justfilename
-            fprintfn out "%s" stringBoilerPlatePrefix
-            fprintfn out "type internal SR private() ="
-            fprintfn out "%s" (StringBoilerPlate justfilename)
-            // gen each resource method
-            stringInfos |> Seq.iter (fun (lineNum, (optErrNum,ident), str, holes, netFormatString) ->
-                let formalArgs = new System.Text.StringBuilder()
-                let actualArgs = new System.Text.StringBuilder()
-                let firstTime = ref true
-                let n = ref 0
-                formalArgs.Append("(") |> ignore
-                for hole in holes do
-                    if !firstTime then
-                        firstTime := false
-                    else
-                        formalArgs.Append(", ") |> ignore
-                        actualArgs.Append(" ") |> ignore
-                    formalArgs.Append(sprintf "a%d : %s" !n (HoleTypeToString hole)) |> ignore
-                    actualArgs.Append(sprintf "a%d" !n) |> ignore
-                    n := !n + 1
-                formalArgs.Append(")") |> ignore
-                fprintfn out "    /// %s" str
-                fprintfn out "    /// (Originally from %s:%d)" filename (lineNum+1)
-                let justPercentsFromFormatString = 
-                    (holes |> Array.fold (fun acc holeType -> 
-                        acc + match holeType with 
-                              | HoleType.Int -> ",,,%d" 
-                              | HoleType.Float -> ",,,%f" 
-                              | HoleType.String -> ",,,%s"
-                              | _ -> failwith "Impossible HoleType") "") + ",,,"
-                let errPrefix = match optErrNum with
-                                | None -> ""
-                                | Some(n) -> sprintf "%d, " n
-                fprintfn out "    static member %s%s = (%sGetStringFunc(\"%s\",\"%s\") %s)" ident (formalArgs.ToString()) errPrefix ident justPercentsFromFormatString (actualArgs.ToString())
-            )
-            fprintfn out ""
-            // gen validation method
-            fprintfn out "    /// Call this method once to validate that all known resources are valid; throws if not"
-            fprintfn out "    static member RunStartupValidation() ="
-            stringInfos |> Seq.iter (fun (lineNum, (optErrNum,ident), str, holes, netFormatString) ->
-                fprintfn out "        ignore(GetString(\"%s\"))" ident
-            )
-            fprintfn out "        ()"  // in case there are 0 strings, we need the generated code to parse
-            // gen to resx
-            let xd = new System.Xml.XmlDocument()
-            xd.LoadXml(xmlBoilerPlateString)
-            stringInfos |> Seq.iter (fun (lineNum, (optErrNum,ident), str, holes, netFormatString) ->
-                let xn = xd.CreateElement("data")
-                xn.SetAttribute("name",ident) |> ignore
-                xn.SetAttribute("xml:space","preserve") |> ignore
-                let xnc = xd.CreateElement("value")
-                xn.AppendChild(xnc) |> ignore
-                xnc.AppendChild(xd.CreateTextNode(netFormatString)) |> ignore
-                xd.LastChild.AppendChild(xn) |> ignore
-            )
-            xd.Save(outXmlFilename)
-            0
-        with 
-            e -> JustPrintErr(filename, 0, sprintf "An exception occurred when processing '%s': %s" filename e.Message)
-                 1
-
-namespace MainImpl
-
-module MainStuff =
-
-    [<EntryPoint>]
-    let Main(args) = FSSRGen.Implementation.RunMain(args)
+namespace FSSRGen
+
+module Implementation =
+    let JustPrintErr(filename, line, msg) =
+        printfn "%s(%d): error : %s" filename line msg
+        
+    /// Err(filename, line, msg)
+    let Err(filename, line, msg) =
+        JustPrintErr(filename, line, msg)
+        printfn "Note that the syntax of each line is one of these three alternatives:"
+        printfn "# comment"
+        printfn "ident,\"string\""
+        printfn "errNum,ident,\"string\""
+        failwithf "there were errors in the file '%s'" filename
+
+    let xmlBoilerPlateString = @"<?xml version=""1.0"" encoding=""utf-8""?>
+    <root>
+      <!-- 
+        Microsoft ResX Schema 
+        
+        Version 2.0
+        
+        The primary goals of this format is to allow a simple XML format 
+        that is mostly human readable. The generation and parsing of the 
+        various data types are done through the TypeConverter classes 
+        associated with the data types.
+        
+        Example:
+        
+        ... ado.net/XML headers & schema ...
+        <resheader name=""resmimetype"">text/microsoft-resx</resheader>
+        <resheader name=""version"">2.0</resheader>
+        <resheader name=""reader"">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+        <resheader name=""writer"">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+        <data name=""Name1""><value>this is my long string</value><comment>this is a comment</comment></data>
+        <data name=""Color1"" type=""System.Drawing.Color, System.Drawing"">Blue</data>
+        <data name=""Bitmap1"" mimetype=""application/x-microsoft.net.object.binary.base64"">
+            <value>[base64 mime encoded serialized .NET Framework object]</value>
+        </data>
+        <data name=""Icon1"" type=""System.Drawing.Icon, System.Drawing"" mimetype=""application/x-microsoft.net.object.bytearray.base64"">
+            <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+            <comment>This is a comment</comment>
+        </data>
+                    
+        There are any number of ""resheader"" rows that contain simple 
+        name/value pairs.
+        
+        Each data row contains a name, and value. The row also contains a 
+        type or mimetype. Type corresponds to a .NET class that support 
+        text/value conversion through the TypeConverter architecture. 
+        Classes that don't support this are serialized and stored with the 
+        mimetype set.
+        
+        The mimetype is used for serialized objects, and tells the 
+        ResXResourceReader how to depersist the object. This is currently not 
+        extensible. For a given mimetype the value must be set accordingly:
+        
+        Note - application/x-microsoft.net.object.binary.base64 is the format 
+        that the ResXResourceWriter will generate, however the reader can 
+        read any of the formats listed below.
+        
+        mimetype: application/x-microsoft.net.object.binary.base64
+        value   : The object must be serialized with 
+                : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+                : and then encoded with base64 encoding.
+        
+        mimetype: application/x-microsoft.net.object.soap.base64
+        value   : The object must be serialized with 
+                : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+                : and then encoded with base64 encoding.
+
+        mimetype: application/x-microsoft.net.object.bytearray.base64
+        value   : The object must be serialized into a byte array 
+                : using a System.ComponentModel.TypeConverter
+                : and then encoded with base64 encoding.
+        -->
+      <xsd:schema id=""root"" xmlns="""" xmlns:xsd=""http://www.w3.org/2001/XMLSchema"" xmlns:msdata=""urn:schemas-microsoft-com:xml-msdata"">
+        <xsd:import namespace=""http://www.w3.org/XML/1998/namespace"" />
+        <xsd:element name=""root"" msdata:IsDataSet=""true"">
+          <xsd:complexType>
+            <xsd:choice maxOccurs=""unbounded"">
+              <xsd:element name=""metadata"">
+                <xsd:complexType>
+                  <xsd:sequence>
+                    <xsd:element name=""value"" type=""xsd:string"" minOccurs=""0"" />
+                  </xsd:sequence>
+                  <xsd:attribute name=""name"" use=""required"" type=""xsd:string"" />
+                  <xsd:attribute name=""type"" type=""xsd:string"" />
+                  <xsd:attribute name=""mimetype"" type=""xsd:string"" />
+                  <xsd:attribute ref=""xml:space"" />
+                </xsd:complexType>
+              </xsd:element>
+              <xsd:element name=""assembly"">
+                <xsd:complexType>
+                  <xsd:attribute name=""alias"" type=""xsd:string"" />
+                  <xsd:attribute name=""name"" type=""xsd:string"" />
+                </xsd:complexType>
+              </xsd:element>
+              <xsd:element name=""data"">
+                <xsd:complexType>
+                  <xsd:sequence>
+                    <xsd:element name=""value"" type=""xsd:string"" minOccurs=""0"" msdata:Ordinal=""1"" />
+                    <xsd:element name=""comment"" type=""xsd:string"" minOccurs=""0"" msdata:Ordinal=""2"" />
+                  </xsd:sequence>
+                  <xsd:attribute name=""name"" type=""xsd:string"" use=""required"" msdata:Ordinal=""1"" />
+                  <xsd:attribute name=""type"" type=""xsd:string"" msdata:Ordinal=""3"" />
+                  <xsd:attribute name=""mimetype"" type=""xsd:string"" msdata:Ordinal=""4"" />
+                  <xsd:attribute ref=""xml:space"" />
+                </xsd:complexType>
+              </xsd:element>
+              <xsd:element name=""resheader"">
+                <xsd:complexType>
+                  <xsd:sequence>
+                    <xsd:element name=""value"" type=""xsd:string"" minOccurs=""0"" msdata:Ordinal=""1"" />
+                  </xsd:sequence>
+                  <xsd:attribute name=""name"" type=""xsd:string"" use=""required"" />
+                </xsd:complexType>
+              </xsd:element>
+            </xsd:choice>
+          </xsd:complexType>
+        </xsd:element>
+      </xsd:schema>
+      <resheader name=""resmimetype"">
+        <value>text/microsoft-resx</value>
+      </resheader>
+      <resheader name=""version"">
+        <value>2.0</value>
+      </resheader>
+      <resheader name=""reader"">
+        <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+      </resheader>
+      <resheader name=""writer"">
+        <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+      </resheader>
+    </root>"
+
+
+
+
+    // The kinds of 'holes' we can do
+    type HoleType =
+        | Int = 0     // %d
+        | String = 1  // %s
+        | Float = 2   // %f
+
+    let HoleTypeToString this =    
+        match this with
+        | HoleType.Int -> "System.Int32"
+        | HoleType.String -> "System.String"
+        | HoleType.Float -> "System.Double"
+        | _ -> failwith "impossible"
+        
+    let ComputeHoles filename lineNum (txt:string) : HoleType[] * string =
+        // takes in a %d%s kind of string, returns array of HoleType and {0}{1} kind of string
+        let mutable i = 0
+        let holeNumber = ref 0
+        let holes = ref []  // reverse order
+        let sb = new System.Text.StringBuilder()
+        let AddHole holeType =
+            sb.Append(sprintf "{%d}" !holeNumber) |> ignore
+            holeNumber := !holeNumber + 1
+            holes := holeType :: !holes
+        while i < txt.Length do
+            if txt.[i] = '%' then
+                if i+1 = txt.Length then
+                    Err(filename, lineNum, "(at end of string) % must be followed by d, f, s, or %")
+                else
+                    match txt.[i+1] with
+                    | 'd' -> AddHole HoleType.Int
+                    | 'f' -> AddHole HoleType.Float
+                    | 's' -> AddHole HoleType.String
+                    | '%' -> sb.Append('%') |> ignore
+                    | c -> Err(filename, lineNum, sprintf "'%%%c' is not a valid sequence, only %%d %%f %%s or %%%%" c)
+                i <- i + 2
+            else
+                match txt.[i] with
+                | '{' -> sb.Append("{{") |> ignore
+                | '}' -> sb.Append("}}") |> ignore
+                | c -> sb.Append(c) |> ignore
+                i <- i + 1
+        (!holes |> List.rev |> List.toArray, sb.ToString())
+
+    let Unquote (s : string) =
+        if s.StartsWith("\"") && s.EndsWith("\"") then s.Substring(1, s.Length - 2)
+        else failwith "error message string should be quoted"
+
+    let ParseLine filename lineNum (txt:string) =
+        let mutable errNum = None
+        let identB = new System.Text.StringBuilder()
+        let mutable i = 0
+        // parse optional error number
+        if i < txt.Length && System.Char.IsDigit(txt.[i]) then
+            let numB = new System.Text.StringBuilder()
+            while i < txt.Length && System.Char.IsDigit(txt.[i]) do
+                numB.Append(txt.[i]) |> ignore
+                i <- i + 1
+            errNum <- Some(int (numB.ToString()))
+            if i = txt.Length || not(txt.[i] = ',') then
+                Err(filename, lineNum, sprintf "After the error number '%d' there should be a comma" errNum.Value)
+            // Skip the comma
+            i <- i + 1
+        // parse short identifier
+        if i < txt.Length && not(System.Char.IsLetter(txt.[i])) then
+            Err(filename, lineNum, sprintf "The first character in the short identifier should be a letter, but found '%c'" txt.[i])
+        while i < txt.Length && System.Char.IsLetterOrDigit(txt.[i]) do
+            identB.Append(txt.[i]) |> ignore
+            i <- i + 1
+        let ident = identB.ToString()
+        if ident.Length = 0 then
+            Err(filename, lineNum, "Did not find the short identifier")
+        else
+            if i = txt.Length || not(txt.[i] = ',') then
+                Err(filename, lineNum, sprintf "After the identifier '%s' there should be a comma" ident)
+            else
+                // Skip the comma
+                i <- i + 1
+                if i = txt.Length then
+                    Err(filename, lineNum, sprintf "After the identifier '%s' and comma, there should be the quoted string resource" ident)
+                else
+                    let str = 
+                        try
+                            System.String.Format(Unquote(txt.Substring(i)))  // Format turns e.g '\n' into that char, but also requires that we 'escape' curlies in the original .txt file, e.g. "{{"
+                        with 
+                            e -> Err(filename, lineNum, sprintf "Error calling System.String.Format (note that curly braces must be escaped, and there cannot be trailing space on the line): >>>%s<<< -- %s" (txt.Substring(i)) e.Message)
+                    let holes, netFormatString = ComputeHoles filename lineNum str
+                    (lineNum, (errNum,ident), str, holes, netFormatString)
+
+    let stringBoilerPlatePrefix = @"            
+open Microsoft.FSharp.Core.LanguagePrimitives.IntrinsicOperators
+open Microsoft.FSharp.Reflection
+open System.Reflection
+// (namespaces below for specific case of using the tool to compile FSharp.Core itself)
+open Microsoft.FSharp.Core
+open Microsoft.FSharp.Core.Operators
+open Microsoft.FSharp.Text
+open Microsoft.FSharp.Collections
+open Printf
+"
+    let StringBoilerPlate filename = @"            
+    // BEGIN BOILERPLATE        
+    static let resources = lazy (new System.Resources.ResourceManager(""" + filename + @""", System.Reflection.Assembly.GetExecutingAssembly()))
+
+    static let GetString(name:string) =        
+        let s = resources.Value.GetString(name, System.Globalization.CultureInfo.CurrentUICulture)
+#if DEBUG
+        if null = s then
+            System.Diagnostics.Debug.Assert(false, sprintf ""**RESOURCE ERROR**: Resource token %s does not exist!"" name)
+#endif
+        s
+
+    static let mkFunctionValue (tys: System.Type[]) (impl:obj->obj) = 
+        FSharpValue.MakeFunction(FSharpType.MakeFunctionType(tys.[0],tys.[1]), impl)
+        
+    static let funTyC = typeof<(obj -> obj)>.GetGenericTypeDefinition()  
+
+    static let isNamedType(ty:System.Type) = not (ty.IsArray ||  ty.IsByRef ||  ty.IsPointer)
+    static let isFunctionType (ty1:System.Type)  = 
+        isNamedType(ty1) && ty1.IsGenericType && (ty1.GetGenericTypeDefinition()).Equals(funTyC)
+
+    static let rec destFunTy (ty:System.Type) =
+        if isFunctionType ty then 
+            ty, ty.GetGenericArguments() 
+        else
+            match ty.BaseType with 
+            | null -> failwith ""destFunTy: not a function type"" 
+            | b -> destFunTy b 
+
+    static let buildFunctionForOneArgPat (ty: System.Type) impl = 
+        let _,tys = destFunTy ty 
+        let rty = tys.[1]
+        // PERF: this technique is a bit slow (e.g. in simple cases, like 'sprintf ""%x""') 
+        mkFunctionValue tys (fun inp -> impl rty inp)
+                
+    static let capture1 (fmt:string) i args ty (go : obj list -> System.Type -> int -> obj) : obj = 
+        match fmt.[i] with
+        | '%' -> go args ty (i+1) 
+        | 'd'
+        | 'f'
+        | 's' -> buildFunctionForOneArgPat ty (fun rty n -> go (n::args) rty (i+1))
+        | _ -> failwith ""bad format specifier""
+        
+    // newlines and tabs get converted to strings when read from a resource file
+    // this will preserve their original intention    
+    static let postProcessString (s : string) =
+        s.Replace(""\\n"",""\n"").Replace(""\\t"",""\t"").Replace(""\\r"",""\r"").Replace(""\\\"""", ""\"""")
+        
+    static let createMessageString (messageString : string) (fmt : Printf.StringFormat<'T>) : 'T = 
+        let fmt = fmt.Value // here, we use the actual error string, as opposed to the one stored as fmt
+        let len = fmt.Length 
+
+        /// Function to capture the arguments and then run.
+        let rec capture args ty i = 
+            if i >= len ||  (fmt.[i] = '%' && i+1 >= len) then 
+                let b = new System.Text.StringBuilder()    
+                b.AppendFormat(messageString, [| for x in List.rev args -> x |]) |> ignore
+                box(b.ToString())
+            // REVIEW: For these purposes, this should be a nop, but I'm leaving it
+            // in incase we ever decide to support labels for the error format string
+            // E.g., ""<name>%s<foo>%d""
+            elif System.Char.IsSurrogatePair(fmt,i) then 
+               capture args ty (i+2)
+            else
+                match fmt.[i] with
+                | '%' ->
+                    let i = i+1 
+                    capture1 fmt i args ty capture
+                | _ ->
+                    capture args ty (i+1) 
+
+        (unbox (capture [] (typeof<'T>) 0) : 'T)
+
+    static let mutable swallowResourceText = false
+    
+    static let GetStringFunc((messageID : string),(fmt : Printf.StringFormat<'T>)) : 'T =
+        if swallowResourceText then
+            sprintf fmt
+        else
+            let mutable messageString = GetString(messageID)
+            messageString <- postProcessString messageString                            
+            createMessageString messageString fmt
+        
+    /// If set to true, then all error messages will just return the filled 'holes' delimited by ',,,'s - this is for language-neutral testing (e.g. localization-invariant baselines).
+    static member SwallowResourceText with get () = swallowResourceText
+                                      and set (b) = swallowResourceText <- b
+    // END BOILERPLATE        
+    "            
+
+    let RunMain(args:string array) =
+        let filename = System.IO.Path.GetFullPath(args.[0])  // TODO args validation
+        let outFilename = System.IO.Path.GetFullPath(args.[1])  // TODO args validation
+        let outXmlFilename = System.IO.Path.GetFullPath(args.[2])  // TODO args validation
+        try
+            let justfilename = System.IO.Path.GetFileNameWithoutExtension(filename)
+            if justfilename |> Seq.exists (fun c -> not(System.Char.IsLetterOrDigit(c))) then
+                Err(filename, 0, sprintf "The filename '%s' is not allowed; only letters and digits can be used, as the filename also becomes the namespace for the SR class" justfilename)
+
+            let lines = System.IO.File.ReadAllLines(filename) 
+                        |> Array.mapi (fun i s -> i,s) // keep line numbers
+                        |> Array.filter (fun (i,s) -> not(s.StartsWith("#")))  // filter out comments
+            let stringInfos = lines |> Array.map (fun (i,s) -> ParseLine filename i s)
+            // now we have array of (lineNum, ident, str, holes, netFormatString)  // str has %d, netFormatString has {0}
+            
+            // validate that all the idents are unique
+            let allIdents = new System.Collections.Generic.Dictionary<string,int>()
+            for (line,(_,ident),_,_,_) in stringInfos do
+                if allIdents.ContainsKey(ident) then
+                    Err(filename,line,sprintf "Identifier '%s' is already used previously on line %d - each identifier must be unique" ident allIdents.[ident])
+                allIdents.Add(ident,line)
+            
+            // validate that all the strings themselves are unique
+            let allStrs = new System.Collections.Generic.Dictionary<string,(int*string)>()
+            for (line,(_,ident),str,_,_) in stringInfos do
+                if allStrs.ContainsKey(str) then
+                    let prevLine,prevIdent = allStrs.[str]
+                    Err(filename,line,sprintf "String '%s' already appears on line %d with identifier '%s' - each string must be unique" str prevLine prevIdent)
+                allStrs.Add(str,(line,ident))
+            
+            use out = new System.IO.StreamWriter(outFilename)
+            fprintfn out "// This is a generated file; the original input is '%s'" filename
+            fprintfn out "namespace %s" justfilename
+            fprintfn out "%s" stringBoilerPlatePrefix
+            fprintfn out "type internal SR private() ="
+            fprintfn out "%s" (StringBoilerPlate justfilename)
+            // gen each resource method
+            stringInfos |> Seq.iter (fun (lineNum, (optErrNum,ident), str, holes, netFormatString) ->
+                let formalArgs = new System.Text.StringBuilder()
+                let actualArgs = new System.Text.StringBuilder()
+                let firstTime = ref true
+                let n = ref 0
+                formalArgs.Append("(") |> ignore
+                for hole in holes do
+                    if !firstTime then
+                        firstTime := false
+                    else
+                        formalArgs.Append(", ") |> ignore
+                        actualArgs.Append(" ") |> ignore
+                    formalArgs.Append(sprintf "a%d : %s" !n (HoleTypeToString hole)) |> ignore
+                    actualArgs.Append(sprintf "a%d" !n) |> ignore
+                    n := !n + 1
+                formalArgs.Append(")") |> ignore
+                fprintfn out "    /// %s" str
+                fprintfn out "    /// (Originally from %s:%d)" filename (lineNum+1)
+                let justPercentsFromFormatString = 
+                    (holes |> Array.fold (fun acc holeType -> 
+                        acc + match holeType with 
+                              | HoleType.Int -> ",,,%d" 
+                              | HoleType.Float -> ",,,%f" 
+                              | HoleType.String -> ",,,%s"
+                              | _ -> failwith "Impossible HoleType") "") + ",,,"
+                let errPrefix = match optErrNum with
+                                | None -> ""
+                                | Some(n) -> sprintf "%d, " n
+                fprintfn out "    static member %s%s = (%sGetStringFunc(\"%s\",\"%s\") %s)" ident (formalArgs.ToString()) errPrefix ident justPercentsFromFormatString (actualArgs.ToString())
+            )
+            fprintfn out ""
+            // gen validation method
+            fprintfn out "    /// Call this method once to validate that all known resources are valid; throws if not"
+            fprintfn out "    static member RunStartupValidation() ="
+            stringInfos |> Seq.iter (fun (lineNum, (optErrNum,ident), str, holes, netFormatString) ->
+                fprintfn out "        ignore(GetString(\"%s\"))" ident
+            )
+            fprintfn out "        ()"  // in case there are 0 strings, we need the generated code to parse
+            // gen to resx
+            let xd = new System.Xml.XmlDocument()
+            xd.LoadXml(xmlBoilerPlateString)
+            stringInfos |> Seq.iter (fun (lineNum, (optErrNum,ident), str, holes, netFormatString) ->
+                let xn = xd.CreateElement("data")
+                xn.SetAttribute("name",ident) |> ignore
+                xn.SetAttribute("xml:space","preserve") |> ignore
+                let xnc = xd.CreateElement("value")
+                xn.AppendChild(xnc) |> ignore
+                xnc.AppendChild(xd.CreateTextNode(netFormatString)) |> ignore
+                xd.LastChild.AppendChild(xn) |> ignore
+            )
+            xd.Save(outXmlFilename)
+            0
+        with 
+            e -> JustPrintErr(filename, 0, sprintf "An exception occurred when processing '%s': %s" filename e.Message)
+                 1
+
+namespace MainImpl
+
+module MainStuff =
+
+    [<EntryPoint>]
+    let Main(args) = FSSRGen.Implementation.RunMain(args)
--- fsharp-3.1.1.26+dfsg2.orig/FsYacc/FsYacc.fsproj.vspscc
+++ fsharp-3.1.1.26+dfsg2/FsYacc/FsYacc.fsproj.vspscc
@@ -1,10 +1,10 @@
-﻿""
-{
-"FILE_VERSION" = "9237"
-"ENLISTMENT_CHOICE" = "NEVER"
-"PROJECT_FILE_RELATIVE_PATH" = ""
-"NUMBER_OF_EXCLUDED_FILES" = "0"
-"ORIGINAL_PROJECT_FILE_PATH" = ""
-"NUMBER_OF_NESTED_PROJECTS" = "0"
-"SOURCE_CONTROL_SETTINGS_PROVIDER" = "PROVIDER"
-}
+﻿""
+{
+"FILE_VERSION" = "9237"
+"ENLISTMENT_CHOICE" = "NEVER"
+"PROJECT_FILE_RELATIVE_PATH" = ""
+"NUMBER_OF_EXCLUDED_FILES" = "0"
+"ORIGINAL_PROJECT_FILE_PATH" = ""
+"NUMBER_OF_NESTED_PROJECTS" = "0"
+"SOURCE_CONTROL_SETTINGS_PROVIDER" = "PROVIDER"
+}
--- fsharp-3.1.1.26+dfsg2.orig/FsYacc/assemblyinfo.fsyacc.exe.fs
+++ fsharp-3.1.1.26+dfsg2/FsYacc/assemblyinfo.fsyacc.exe.fs
@@ -1,7 +1,7 @@
-namespace Microsoft.FSharp
-open System.Reflection
-[<assembly:AssemblyDescription("fsyacc.exe")>]
-[<assembly:AssemblyCompany("F# PowerPack CodePlex Project")>]
-[<assembly:AssemblyTitle("fsyacc.exe")>]
-[<assembly:AssemblyProduct("F# Power Pack")>]
-do()
+namespace Microsoft.FSharp
+open System.Reflection
+[<assembly:AssemblyDescription("fsyacc.exe")>]
+[<assembly:AssemblyCompany("F# PowerPack CodePlex Project")>]
+[<assembly:AssemblyTitle("fsyacc.exe")>]
+[<assembly:AssemblyProduct("F# Power Pack")>]
+do()
--- fsharp-3.1.1.26+dfsg2.orig/FsYacc/fsyacc.fs
+++ fsharp-3.1.1.26+dfsg2/FsYacc/fsyacc.fs
@@ -1,531 +1,531 @@
-(* (c) Microsoft Corporation 2005-2008.  *)
-
-module internal FSharp.PowerPack.FsYacc.Driver 
-
-open System.IO 
-open System.Collections.Generic
-open Printf
-open Internal.Utilities
-open Internal.Utilities.Text.Lexing
-
-open FSharp.PowerPack.FsYacc
-open FSharp.PowerPack.FsYacc.AST
-
-//------------------------------------------------------------------
-// This code is duplicated from Microsoft.FSharp.Compiler.UnicodeLexing
-
-type Lexbuf =  LexBuffer<char>
-
-/// Standard utility to create a Unicode LexBuffer
-///
-/// One small annoyance is that LexBuffers and not IDisposable. This means 
-/// we can't just return the LexBuffer object, since the file it wraps wouldn't
-/// get closed when we're finished with the LexBuffer. Hence we return the stream,
-/// the reader and the LexBuffer. The caller should dispose the first two when done.
-let UnicodeFileAsLexbuf (filename,codePage : int option) : FileStream * StreamReader * Lexbuf =
-    // Use the .NET functionality to auto-detect the unicode encoding
-    // It also uses Lexing.from_text_reader to present the bytes read to the lexer in UTF8 decoded form
-    let stream  = new FileStream(filename,FileMode.Open,FileAccess.Read,FileShare.Read) 
-    let reader = 
-        match codePage with 
-        | None -> new  StreamReader(stream,true)
-        | Some n -> new  StreamReader(stream,System.Text.Encoding.GetEncoding(n)) 
-    let lexbuf = LexBuffer<char>.FromFunction(reader.Read) 
-    lexbuf.EndPos <- Position.FirstLine(filename);
-    stream, reader, lexbuf
-
-//------------------------------------------------------------------
-// This is the program proper
-
-let input = ref None
-let modname= ref None
-let internal_module = ref false
-let opens= ref []
-let out = ref None
-let tokenize = ref false
-let compat = ref false
-let log = ref false
-let light = ref None
-let inputCodePage = ref None
-let mutable lexlib = "Microsoft.FSharp.Text.Lexing"
-let mutable parslib = "Microsoft.FSharp.Text.Parsing"
-
-let usage =
-  [ ArgInfo("-o", ArgType.String (fun s -> out := Some s), "Name the output file.");
-    ArgInfo("-v", ArgType.Unit (fun () -> log := true), "Produce a listing file."); 
-    ArgInfo("--module", ArgType.String (fun s -> modname := Some s), "Define the F# module name to host the generated parser."); 
-    ArgInfo("--internal", ArgType.Unit (fun () -> internal_module := true), "Generate an internal module");
-    ArgInfo("--open", ArgType.String (fun s -> opens := !opens @ [s]), "Add the given module to the list of those to open in both the generated signature and implementation."); 
-    ArgInfo("--light", ArgType.Unit (fun () ->  light := Some true), "(ignored)");
-    ArgInfo("--light-off", ArgType.Unit (fun () ->  light := Some false), "Add #light \"off\" to the top of the generated file");
-    ArgInfo("--ml-compatibility", ArgType.Set compat, "Support the use of the global state from the 'Parsing' module in FSharp.PowerPack.dll."); 
-    ArgInfo("--tokens", ArgType.Set tokenize, "Simply tokenize the specification file itself."); 
-    ArgInfo("--lexlib", ArgType.String (fun s ->  lexlib <- s), "Specify the namespace for the implementation of the parser table interperter (default Microsoft.FSharp.Text.Parsing)");
-    ArgInfo("--parslib", ArgType.String (fun s ->  parslib <- s), "Specify the namespace for the implementation of the parser table interperter (default Microsoft.FSharp.Text.Parsing)");
-    ArgInfo("--codepage", ArgType.Int (fun i -> inputCodePage := Some i), "Assume input lexer specification file is encoded with the given codepage.");  ]
-
-let _ = ArgParser.Parse(usage,(fun x -> match !input with Some _ -> failwith "more than one input given" | None -> input := Some x),"fsyacc <filename>")
-
-let output_int (os: #TextWriter) (n:int) = os.Write(string n)
-
-let outputCodedUInt16 (os: #TextWriter)  (n:int) = 
-  os.Write n;
-  os.Write "us; ";
-
-let shiftFlag = 0x0000
-let reduceFlag = 0x4000
-let errorFlag = 0x8000
-let acceptFlag = 0xc000
-let actionMask = 0xc000
-
-let anyMarker = 0xffff
-
-let actionCoding action  =
-  match action with 
-  | Accept -> acceptFlag
-  | Shift n -> shiftFlag ||| n
-  | Reduce n -> reduceFlag ||| n
-  | Error -> errorFlag 
-
-let main() = 
-  let filename = (match !input with Some x -> x | None -> failwith "no input given") in 
-  let spec = 
-      let stream,reader,lexbuf = UnicodeFileAsLexbuf(filename, !inputCodePage) 
-      use stream = stream
-      use reader = reader
-
-      try 
-        if !tokenize then begin 
-          while true do 
-            printf "tokenize - getting one token";
-            let t = Lexer.token lexbuf in 
-            (*F# printf "tokenize - got %s" (Parser.token_to_string t); F#*)
-            if t = Parser.EOF then exit 0;
-          done;
-        end;
-    
-        Parser.spec Lexer.token lexbuf 
-      with e -> 
-         printf "%s(%d,%d): error: %s" filename lexbuf.StartPos.Line lexbuf.StartPos.Column e.Message;
-         exit 1  in
-
-  let has_extension (s:string) = 
-    (s.Length >= 1 && s.[s.Length - 1] = '.') 
-    || Path.HasExtension(s)
-
-  let chop_extension (s:string) =
-    if not (has_extension s) then invalidArg "s" "the file name does not have an extension"
-    Path.Combine (Path.GetDirectoryName s,Path.GetFileNameWithoutExtension(s)) 
-  
-  let checkSuffix (x:string) (y:string) = x.EndsWith(y)
-
-  let output = match !out with Some x -> x | _ -> chop_extension filename + (if checkSuffix filename ".mly" then ".ml" else ".fs") in
-  let outputi = match !out with Some x -> chop_extension x + (if checkSuffix x ".ml" then ".mli" else ".fsi") | _ -> chop_extension filename + (if checkSuffix filename ".mly" then ".mli" else ".fsi") in
-  let outputo = 
-      if !log then Some (match !out with Some x -> chop_extension x + ".fsyacc.output" | _ -> chop_extension filename + ".fsyacc.output") 
-      else None 
-
-  use os = (File.CreateText output :> TextWriter)
-  use osi = (File.CreateText outputi :> TextWriter)
-
-  let lineCountOutput = ref 0
-  let lineCountSignature = ref 0
-  let cos = (os,lineCountOutput)
-  let cosi = (osi,lineCountSignature)
-  let cprintf (os:TextWriter,lineCount) fmt = Printf.fprintf os fmt
-  let cprintfn (os:TextWriter,lineCount) fmt = Printf.kfprintf (fun () -> incr lineCount; os.WriteLine()) os fmt
-
-  let logf = 
-      match outputo with 
-      | None -> (fun f -> ())
-      | Some filename -> 
-          let oso = (File.CreateText filename :> TextWriter) 
-          (fun f -> f oso) 
-
-  logf (fun oso -> fprintfn oso "Output file describing compiled parser placed in %s and %s" output outputi);
-
-  printfn "building tables"; 
-  let spec1 = ProcessParserSpecAst spec 
-  let (prods,states, startStates,actionTable,immediateActionTable,gotoTable,endOfInputTerminalIdx,errorTerminalIdx,nonTerminals) = 
-      CompilerLalrParserSpec logf spec1 
-
-  let (code,pos) = spec.Header 
-  printfn "%d states" states.Length; 
-  printfn "%d nonterminals" gotoTable.[0].Length; 
-  printfn "%d terminals" actionTable.[0].Length; 
-  printfn "%d productions" prods.Length; 
-  printfn "#rows in action table: %d" actionTable.Length; 
-(*
-  printfn "#unique rows in action table: %d" (List.length (Array.foldBack (fun row acc -> insert (Array.to_list row) acc) actionTable [])); 
-  printfn "maximum #different actions per state: %d" (Array.foldBack (fun row acc ->max (List.length (List.foldBack insert (Array.to_list row) [])) acc) actionTable 0); 
-  printfn "average #different actions per state: %d" ((Array.foldBack (fun row acc -> (List.length (List.foldBack insert (Array.to_list row) [])) + acc) actionTable 0) / (Array.length states)); 
-*)
-
-  cprintfn cos "// Implementation file for parser generated by fsyacc";
-  cprintfn cosi "// Signature file for parser generated by fsyacc";
-
-  if (!light = Some(false)) || (!light = None && checkSuffix output ".ml") then
-      cprintfn cos "#light \"off\"";
-      cprintfn cosi "#light \"off\"";
-
-  match !modname with 
-  | None -> ()
-  | Some s -> 
-      match !internal_module with
-      | true ->
-          cprintfn cos "module internal %s" s;
-          cprintfn cosi "module internal %s" s;
-      | false ->
-          cprintfn cos "module %s" s;
-          cprintfn cosi "module %s" s;
-  
-  cprintfn cos "#nowarn \"64\";; // turn off warnings that type variables used in production annotations are instantiated to concrete type";
-
-  for s in !opens do
-      cprintfn cos "open %s" s;
-      cprintfn cosi "open %s" s;
-
-  cprintfn cos "open %s" lexlib;
-  cprintfn cos "open %s.ParseHelpers" parslib;
-  if !compat then 
-      cprintfn cos "open Microsoft.FSharp.Compatibility.OCaml.Parsing";
-
-  cprintfn cos "# %d \"%s\"" pos.pos_lnum pos.pos_fname;
-  cprintfn cos "%s" code;
-  lineCountOutput := !lineCountOutput + code.Replace("\r","").Split([| '\n' |]).Length;
-
-  cprintfn cos "# %d \"%s\"" !lineCountOutput output;
-  // Print the datatype for the tokens
-  cprintfn cos "// This type is the type of tokens accepted by the parser";
-  for out in [cos;cosi] do
-      cprintfn out "type token = ";
-      for id,typ in spec.Tokens do 
-          match typ with
-          | None -> cprintfn out "  | %s" id
-          | Some ty -> cprintfn out "  | %s of (%s)" id ty; 
-
-  // Print the datatype for the token names
-  cprintfn cos "// This type is used to give symbolic names to token indexes, useful for error messages";
-  for out in [cos;cosi] do
-      cprintfn out "type tokenId = ";
-      for id,typ in spec.Tokens do 
-          cprintfn out "    | TOKEN_%s" id;
-      cprintfn out "    | TOKEN_end_of_input";
-      cprintfn out "    | TOKEN_error";
-
-  cprintfn cos "// This type is used to give symbolic names to token indexes, useful for error messages";
-  for out in [cos;cosi] do
-      cprintfn out "type nonTerminalId = ";
-      for nt in nonTerminals do 
-          cprintfn out "    | NONTERM_%s" nt;
-
-  cprintfn cos "";
-  cprintfn cos "// This function maps tokens to integers indexes";
-  cprintfn cos "let tagOfToken (t:token) = ";
-  cprintfn cos "  match t with";
-  spec.Tokens |> List.iteri (fun i (id,typ) -> 
-      cprintfn cos "  | %s %s -> %d " id (match typ with Some _ -> "_" | None -> "") i);
-  cprintfn cosi "/// This function maps integers indexes to symbolic token ids";
-  cprintfn cosi "val tagOfToken: token -> int";
-
-  cprintfn cos "";
-  cprintfn cos "// This function maps integers indexes to symbolic token ids";
-  cprintfn cos "let tokenTagToTokenId (tokenIdx:int) = ";
-  cprintfn cos "  match tokenIdx with";
-  spec.Tokens |> List.iteri (fun i (id,typ) -> 
-      cprintfn cos "  | %d -> TOKEN_%s " i id)
-  cprintfn cos "  | %d -> TOKEN_end_of_input" endOfInputTerminalIdx;
-  cprintfn cos "  | %d -> TOKEN_error" errorTerminalIdx;
-  cprintfn cos "  | _ -> failwith \"tokenTagToTokenId: bad token\""
-
-  cprintfn cosi "";
-  cprintfn cosi "/// This function maps integers indexes to symbolic token ids";
-  cprintfn cosi "val tokenTagToTokenId: int -> tokenId";
-
-  cprintfn cos "";
-  cprintfn cos "/// This function maps production indexes returned in syntax errors to strings representing the non terminal that would be produced by that production";
-  cprintfn cos "let prodIdxToNonTerminal (prodIdx:int) = ";
-  cprintfn cos "  match prodIdx with";
-  prods |> Array.iteri (fun i (nt,ntIdx,syms,code) -> 
-      cprintfn cos "    | %d -> NONTERM_%s " i nt);
-  cprintfn cos "    | _ -> failwith \"prodIdxToNonTerminal: bad production index\""
-
-  cprintfn cosi "";
-  cprintfn cosi "/// This function maps production indexes returned in syntax errors to strings representing the non terminal that would be produced by that production";
-  cprintfn cosi "val prodIdxToNonTerminal: int -> nonTerminalId";
-
-  cprintfn cos "";
-  cprintfn cos "let _fsyacc_endOfInputTag = %d " endOfInputTerminalIdx;
-  cprintfn cos "let _fsyacc_tagOfErrorTerminal = %d" errorTerminalIdx;
-  cprintfn cos "";
-  cprintfn cos "// This function gets the name of a token as a string";
-  cprintfn cos "let token_to_string (t:token) = ";
-  cprintfn cos "  match t with ";
-  spec.Tokens |> List.iteri (fun i (id,typ) -> 
-      cprintfn cos "  | %s %s -> \"%s\" " id (match typ with Some _ -> "_" | None -> "") id);
-
-  cprintfn cosi "";
-  cprintfn cosi "/// This function gets the name of a token as a string";
-  cprintfn cosi "val token_to_string: token -> string";
-
-  cprintfn cos "";
-  cprintfn cos "// This function gets the data carried by a token as an object";
-  cprintfn cos "let _fsyacc_dataOfToken (t:token) = ";
-  cprintfn cos "  match t with ";
-
-  for (id,typ) in spec.Tokens do
-      cprintfn cos "  | %s %s -> %s " 
-        id
-        (match typ with Some _ -> "_fsyacc_x" | None -> "")
-        (match typ with Some _ -> "Microsoft.FSharp.Core.Operators.box _fsyacc_x" | None -> "(null : System.Object)")
-
-  let tychar = "'cty" 
-
-  for (key,_) in spec.Types |> Seq.countBy fst |> Seq.filter (fun (_,n) -> n > 1)  do
-        failwithf "%s is given multiple %%type declarations" key;
-    
-  for (key,_) in spec.Tokens |> Seq.countBy fst |> Seq.filter (fun (_,n) -> n > 1)  do
-        failwithf "%s is given %%token declarations" key
-    
-  let types = Map.ofList spec.Types 
-  let tokens = Map.ofList spec.Tokens 
-  
-  let nStates = states.Length 
-  begin 
-      cprintf cos "let _fsyacc_gotos = [| " ;
-      let numGotoNonTerminals = gotoTable.[0].Length 
-      let gotoIndexes = Array.create numGotoNonTerminals 0 
-      let gotoTableCurrIndex = ref 0 in 
-      for j = 0 to numGotoNonTerminals-1 do  
-          gotoIndexes.[j] <- !gotoTableCurrIndex;
-
-          (* Count the number of entries in the association table. *)
-          let count = ref 0 in 
-          for i = 0 to nStates - 1 do 
-            let goto = gotoTable.[i].[j] 
-            match goto with 
-            | None -> ()
-            | Some _ -> incr count
-   
-          (* Write the head of the table (i.e. the number of entries and the default value) *)
-          gotoTableCurrIndex := !gotoTableCurrIndex + 1;
-          outputCodedUInt16 os !count;
-          outputCodedUInt16 os anyMarker;
-          
-          (* Write the pairs of entries in incremental order by key *)
-          (* This lets us implement the lookup by a binary chop. *)
-          for i = 0 to nStates - 1 do 
-            let goto = gotoTable.[i].[j] 
-            match goto with 
-            | None -> ()
-            | Some n -> 
-                gotoTableCurrIndex := !gotoTableCurrIndex + 1;
-                outputCodedUInt16 os i;
-                outputCodedUInt16 os n;
-      cprintfn cos "|]" ;
-      (* Output offsets into gotos table where the gotos for a particular nonterminal begin *)
-      cprintf cos "let _fsyacc_sparseGotoTableRowOffsets = [|" ;
-      for j = 0 to numGotoNonTerminals-1 do  
-          outputCodedUInt16 os gotoIndexes.[j];
-      cprintfn cos "|]" ;
-  end;
-
-  begin 
-      cprintf cos "let _fsyacc_stateToProdIdxsTableElements = [| " ;
-      let indexes = Array.create states.Length 0 
-      let currIndex = ref 0 
-      for j = 0 to states.Length - 1 do
-          let state = states.[j]
-          indexes.[j] <- !currIndex;
-
-          (* Write the head of the table (i.e. the number of entries) *)
-          outputCodedUInt16 os state.Length;
-          currIndex := !currIndex + state.Length + 1;
-          
-          (* Write the pairs of entries in incremental order by key *)
-          (* This lets us implement the lookup by a binary chop. *)
-          for prodIdx in state do
-                outputCodedUInt16 os prodIdx;
-      cprintfn cos "|]" ;
-      (* Output offsets into gotos table where the gotos for a particular nonterminal begin *)
-      cprintf cos "let _fsyacc_stateToProdIdxsTableRowOffsets = [|" ;
-      for idx in indexes do 
-          outputCodedUInt16 os idx;
-      cprintfn cos "|]" ;
-  end;
-
-  begin 
-    let numActionRows = (Array.length actionTable) 
-    let maxActionColumns = Array.length actionTable.[0] 
-    cprintfn cos "let _fsyacc_action_rows = %d" numActionRows;
-    cprintf cos "let _fsyacc_actionTableElements = [|" ;
-    let actionIndexes = Array.create numActionRows 0 
-    
-    let actionTableCurrIndex = ref 0 
-    for i = 0 to nStates-1 do 
-        actionIndexes.[i] <- !actionTableCurrIndex;
-        let actions = actionTable.[i] 
-        let terminalsByAction = new Dictionary<_,int list>(10) 
-        let countPerAction = new Dictionary<_,_>(10) 
-        for terminal = 0 to actions.Length - 1 do  
-              let action = snd actions.[terminal] 
-              if terminalsByAction.ContainsKey action then 
-                  terminalsByAction.[action] <- terminal :: terminalsByAction.[action] ;
-              else
-                  terminalsByAction.[action] <- [terminal];
-              if countPerAction.ContainsKey action then 
-                countPerAction.[action] <- countPerAction.[action]+1
-              else 
-                countPerAction.[action] <- 1
-
-        let mostCommonAction = 
-            let mostCommon = ref Error 
-            let max = ref 0 
-            for (KeyValue(x,y)) in countPerAction do 
-                if y > !max then (mostCommon := x; max := y)
-            !mostCommon 
-
-        (* Count the number of entries in the association table. *)
-        let count = ref 0 
-        for (KeyValue(action,terminals)) in terminalsByAction do 
-            for terminals  in terminals do 
-               if action <> mostCommonAction then  
-                   incr count;
-        
-        (* Write the head of the table (i.e. the number of entries and the default value) *)
-        actionTableCurrIndex := !actionTableCurrIndex + 1;
-        outputCodedUInt16 os !count;
-        outputCodedUInt16 os (actionCoding mostCommonAction);
-        
-        (* Write the pairs of entries in incremental order by key *)
-        (* This lets us implement the lookup by a binary chop. *)
-        for terminal = 0 to Array.length actions-1 do  
-            let action = snd actions.[terminal] in 
-            if action <> mostCommonAction then  (
-                actionTableCurrIndex := !actionTableCurrIndex + 1;
-                outputCodedUInt16 os terminal;
-                outputCodedUInt16 os (actionCoding action);
-            );
-    cprintfn cos "|]" ;
-    (* Output offsets into actions table where the actions for a particular nonterminal begin *)
-    cprintf cos "let _fsyacc_actionTableRowOffsets = [|" ;
-    for j = 0 to numActionRows-1 do  
-        cprintf cos "%a" outputCodedUInt16 actionIndexes.[j];
-    cprintfn cos "|]" ;
-
-  end;
-  begin 
-      cprintf cos "let _fsyacc_reductionSymbolCounts = [|" ;
-      for nt,ntIdx,syms,code in prods do 
-          cprintf cos "%a" outputCodedUInt16 (List.length syms);
-      cprintfn cos "|]" ;
-  end;
-  begin 
-      cprintf cos "let _fsyacc_productionToNonTerminalTable = [|" ;
-      for nt,ntIdx,syms,code in prods do 
-          cprintf cos "%a" outputCodedUInt16 ntIdx;
-      cprintfn cos "|]" ;
-  end;
-  begin 
-      cprintf cos "let _fsyacc_immediateActions = [|" ;
-      for prodIdx in immediateActionTable do 
-          match prodIdx with
-            | None     -> cprintf cos "%a" outputCodedUInt16 anyMarker (* NONE REP *)
-            | Some act -> cprintf cos "%a" outputCodedUInt16 (actionCoding act)
-      cprintfn cos "|]" ;
-  end;
-  
-  let getType nt = if types.ContainsKey nt then  types.[nt] else "'"+nt 
-  begin 
-      cprintf cos "let _fsyacc_reductions ()  =" ;
-      cprintfn cos "    [| " ;
-      for nt,ntIdx,syms,code in prods do 
-          cprintfn cos "# %d \"%s\"" !lineCountOutput output;
-          cprintfn cos "        (fun (parseState : %s.IParseState) ->"  parslib
-          if !compat then 
-              cprintfn cos "            Parsing.set_parse_state parseState;"
-          syms |> List.iteri (fun i sym -> 
-              let tyopt = 
-                  match sym with
-                  | Terminal t -> 
-                      if tokens.ContainsKey t then 
-                        tokens.[t]
-                      else None
-                  | NonTerminal nt -> Some (getType nt) 
-              match tyopt with 
-              | Some ty -> cprintfn cos "            let _%d = (let data = parseState.GetInput(%d) in (Microsoft.FSharp.Core.Operators.unbox data : %s)) in" (i+1) (i+1) ty
-              | None -> ())
-          cprintfn cos "            Microsoft.FSharp.Core.Operators.box" 
-          cprintfn cos "                (";
-          cprintfn cos "                   (";
-          match code with 
-          | Some (_,pos) -> cprintfn cos "# %d \"%s\"" pos.pos_lnum pos.pos_fname
-          | None -> ()
-          match code with 
-          | Some (code,_) -> 
-              let dollar = ref false in 
-              let c = code |> String.collect (fun c -> 
-                  if not !dollar && c = '$' then (dollar := true; "")
-                  elif !dollar && c >= '0' && c <= '9' then (dollar := false; "_"+new System.String(c,1))
-                  elif !dollar then (dollar := false; "$"+new System.String(c,1))
-                  else new System.String(c,1))
-              let lines = c.Split([| '\r'; '\n' |], System.StringSplitOptions.RemoveEmptyEntries);
-              for line in lines do 
-                  cprintfn cos "                     %s" line;
-              if !dollar then os.Write '$'
-          | None -> 
-              cprintfn cos "                      raise (%s.Accept(Microsoft.FSharp.Core.Operators.box _1))" parslib
-          cprintfn cos "                   )";
-          // Place the line count back for the type constraint
-          match code with 
-          | Some (_,pos) -> cprintfn cos "# %d \"%s\"" pos.pos_lnum pos.pos_fname
-          | None -> ()
-          cprintfn cos "                 : %s));" (if types.ContainsKey nt then  types.[nt] else "'"+nt);
-      done;
-      cprintfn cos "|]" ;
-  end;
-  cprintfn cos "# %d \"%s\"" !lineCountOutput output;
-  cprintfn cos "let tables () : %s.Tables<_> = " parslib
-  cprintfn cos "  { reductions= _fsyacc_reductions ();"
-  cprintfn cos "    endOfInputTag = _fsyacc_endOfInputTag;"
-  cprintfn cos "    tagOfToken = tagOfToken;"
-  cprintfn cos "    dataOfToken = _fsyacc_dataOfToken; "
-  cprintfn cos "    actionTableElements = _fsyacc_actionTableElements;"
-  cprintfn cos "    actionTableRowOffsets = _fsyacc_actionTableRowOffsets;"
-  cprintfn cos "    stateToProdIdxsTableElements = _fsyacc_stateToProdIdxsTableElements;"
-  cprintfn cos "    stateToProdIdxsTableRowOffsets = _fsyacc_stateToProdIdxsTableRowOffsets;"
-  cprintfn cos "    reductionSymbolCounts = _fsyacc_reductionSymbolCounts;"
-  cprintfn cos "    immediateActions = _fsyacc_immediateActions;"
-  cprintfn cos "    gotos = _fsyacc_gotos;"
-  cprintfn cos "    sparseGotoTableRowOffsets = _fsyacc_sparseGotoTableRowOffsets;"
-  cprintfn cos "    tagOfErrorTerminal = _fsyacc_tagOfErrorTerminal;"
-  cprintfn cos "    parseError = (fun (ctxt:%s.ParseErrorContext<_>) -> " parslib
-  cprintfn cos "                              match parse_error_rich with "
-  cprintfn cos "                              | Some f -> f ctxt"
-  cprintfn cos "                              | None -> parse_error ctxt.Message);"
-  
-  cprintfn cos "    numTerminals = %d;" (Array.length actionTable.[0]);
-  cprintfn cos "    productionToNonTerminalTable = _fsyacc_productionToNonTerminalTable  }"
-  cprintfn cos "let engine lexer lexbuf startState = (tables ()).Interpret(lexer, lexbuf, startState)"                                                                                                         
-
-  for (id,startState) in List.zip spec.StartSymbols startStates do
-        if not (types.ContainsKey id) then 
-          failwith ("a %type declaration is required for for start token "+id);
-        let ty = types.[id] in 
-        cprintfn cos "let %s lexer lexbuf : %s =" id ty;
-        cprintfn cos "    Microsoft.FSharp.Core.Operators.unbox ((tables ()).Interpret(lexer, lexbuf, %d))" startState
-
-  for id in spec.StartSymbols do
-      if not (types.ContainsKey id) then 
-        failwith ("a %type declaration is required for start token "+id);
-      let ty = types.[id] in 
-      cprintfn cosi "val %s : (%s.LexBuffer<%s> -> token) -> %s.LexBuffer<%s> -> (%s) " id lexlib tychar lexlib tychar ty;
-
-  logf (fun oso -> oso.Close())
-
-let _ = 
-    try main()
-    with e -> 
-      printf "FSYACC: error FSY000: %s" (match e with Failure s -> s | e -> e.Message);
-      exit 1
-
+(* (c) Microsoft Corporation 2005-2008.  *)
+
+module internal FSharp.PowerPack.FsYacc.Driver 
+
+open System.IO 
+open System.Collections.Generic
+open Printf
+open Internal.Utilities
+open Internal.Utilities.Text.Lexing
+
+open FSharp.PowerPack.FsYacc
+open FSharp.PowerPack.FsYacc.AST
+
+//------------------------------------------------------------------
+// This code is duplicated from Microsoft.FSharp.Compiler.UnicodeLexing
+
+type Lexbuf =  LexBuffer<char>
+
+/// Standard utility to create a Unicode LexBuffer
+///
+/// One small annoyance is that LexBuffers and not IDisposable. This means 
+/// we can't just return the LexBuffer object, since the file it wraps wouldn't
+/// get closed when we're finished with the LexBuffer. Hence we return the stream,
+/// the reader and the LexBuffer. The caller should dispose the first two when done.
+let UnicodeFileAsLexbuf (filename,codePage : int option) : FileStream * StreamReader * Lexbuf =
+    // Use the .NET functionality to auto-detect the unicode encoding
+    // It also uses Lexing.from_text_reader to present the bytes read to the lexer in UTF8 decoded form
+    let stream  = new FileStream(filename,FileMode.Open,FileAccess.Read,FileShare.Read) 
+    let reader = 
+        match codePage with 
+        | None -> new  StreamReader(stream,true)
+        | Some n -> new  StreamReader(stream,System.Text.Encoding.GetEncoding(n)) 
+    let lexbuf = LexBuffer<char>.FromFunction(reader.Read) 
+    lexbuf.EndPos <- Position.FirstLine(filename);
+    stream, reader, lexbuf
+
+//------------------------------------------------------------------
+// This is the program proper
+
+let input = ref None
+let modname= ref None
+let internal_module = ref false
+let opens= ref []
+let out = ref None
+let tokenize = ref false
+let compat = ref false
+let log = ref false
+let light = ref None
+let inputCodePage = ref None
+let mutable lexlib = "Microsoft.FSharp.Text.Lexing"
+let mutable parslib = "Microsoft.FSharp.Text.Parsing"
+
+let usage =
+  [ ArgInfo("-o", ArgType.String (fun s -> out := Some s), "Name the output file.");
+    ArgInfo("-v", ArgType.Unit (fun () -> log := true), "Produce a listing file."); 
+    ArgInfo("--module", ArgType.String (fun s -> modname := Some s), "Define the F# module name to host the generated parser."); 
+    ArgInfo("--internal", ArgType.Unit (fun () -> internal_module := true), "Generate an internal module");
+    ArgInfo("--open", ArgType.String (fun s -> opens := !opens @ [s]), "Add the given module to the list of those to open in both the generated signature and implementation."); 
+    ArgInfo("--light", ArgType.Unit (fun () ->  light := Some true), "(ignored)");
+    ArgInfo("--light-off", ArgType.Unit (fun () ->  light := Some false), "Add #light \"off\" to the top of the generated file");
+    ArgInfo("--ml-compatibility", ArgType.Set compat, "Support the use of the global state from the 'Parsing' module in FSharp.PowerPack.dll."); 
+    ArgInfo("--tokens", ArgType.Set tokenize, "Simply tokenize the specification file itself."); 
+    ArgInfo("--lexlib", ArgType.String (fun s ->  lexlib <- s), "Specify the namespace for the implementation of the parser table interperter (default Microsoft.FSharp.Text.Parsing)");
+    ArgInfo("--parslib", ArgType.String (fun s ->  parslib <- s), "Specify the namespace for the implementation of the parser table interperter (default Microsoft.FSharp.Text.Parsing)");
+    ArgInfo("--codepage", ArgType.Int (fun i -> inputCodePage := Some i), "Assume input lexer specification file is encoded with the given codepage.");  ]
+
+let _ = ArgParser.Parse(usage,(fun x -> match !input with Some _ -> failwith "more than one input given" | None -> input := Some x),"fsyacc <filename>")
+
+let output_int (os: #TextWriter) (n:int) = os.Write(string n)
+
+let outputCodedUInt16 (os: #TextWriter)  (n:int) = 
+  os.Write n;
+  os.Write "us; ";
+
+let shiftFlag = 0x0000
+let reduceFlag = 0x4000
+let errorFlag = 0x8000
+let acceptFlag = 0xc000
+let actionMask = 0xc000
+
+let anyMarker = 0xffff
+
+let actionCoding action  =
+  match action with 
+  | Accept -> acceptFlag
+  | Shift n -> shiftFlag ||| n
+  | Reduce n -> reduceFlag ||| n
+  | Error -> errorFlag 
+
+let main() = 
+  let filename = (match !input with Some x -> x | None -> failwith "no input given") in 
+  let spec = 
+      let stream,reader,lexbuf = UnicodeFileAsLexbuf(filename, !inputCodePage) 
+      use stream = stream
+      use reader = reader
+
+      try 
+        if !tokenize then begin 
+          while true do 
+            printf "tokenize - getting one token";
+            let t = Lexer.token lexbuf in 
+            (*F# printf "tokenize - got %s" (Parser.token_to_string t); F#*)
+            if t = Parser.EOF then exit 0;
+          done;
+        end;
+    
+        Parser.spec Lexer.token lexbuf 
+      with e -> 
+         printf "%s(%d,%d): error: %s" filename lexbuf.StartPos.Line lexbuf.StartPos.Column e.Message;
+         exit 1  in
+
+  let has_extension (s:string) = 
+    (s.Length >= 1 && s.[s.Length - 1] = '.') 
+    || Path.HasExtension(s)
+
+  let chop_extension (s:string) =
+    if not (has_extension s) then invalidArg "s" "the file name does not have an extension"
+    Path.Combine (Path.GetDirectoryName s,Path.GetFileNameWithoutExtension(s)) 
+  
+  let checkSuffix (x:string) (y:string) = x.EndsWith(y)
+
+  let output = match !out with Some x -> x | _ -> chop_extension filename + (if checkSuffix filename ".mly" then ".ml" else ".fs") in
+  let outputi = match !out with Some x -> chop_extension x + (if checkSuffix x ".ml" then ".mli" else ".fsi") | _ -> chop_extension filename + (if checkSuffix filename ".mly" then ".mli" else ".fsi") in
+  let outputo = 
+      if !log then Some (match !out with Some x -> chop_extension x + ".fsyacc.output" | _ -> chop_extension filename + ".fsyacc.output") 
+      else None 
+
+  use os = (File.CreateText output :> TextWriter)
+  use osi = (File.CreateText outputi :> TextWriter)
+
+  let lineCountOutput = ref 0
+  let lineCountSignature = ref 0
+  let cos = (os,lineCountOutput)
+  let cosi = (osi,lineCountSignature)
+  let cprintf (os:TextWriter,lineCount) fmt = Printf.fprintf os fmt
+  let cprintfn (os:TextWriter,lineCount) fmt = Printf.kfprintf (fun () -> incr lineCount; os.WriteLine()) os fmt
+
+  let logf = 
+      match outputo with 
+      | None -> (fun f -> ())
+      | Some filename -> 
+          let oso = (File.CreateText filename :> TextWriter) 
+          (fun f -> f oso) 
+
+  logf (fun oso -> fprintfn oso "Output file describing compiled parser placed in %s and %s" output outputi);
+
+  printfn "building tables"; 
+  let spec1 = ProcessParserSpecAst spec 
+  let (prods,states, startStates,actionTable,immediateActionTable,gotoTable,endOfInputTerminalIdx,errorTerminalIdx,nonTerminals) = 
+      CompilerLalrParserSpec logf spec1 
+
+  let (code,pos) = spec.Header 
+  printfn "%d states" states.Length; 
+  printfn "%d nonterminals" gotoTable.[0].Length; 
+  printfn "%d terminals" actionTable.[0].Length; 
+  printfn "%d productions" prods.Length; 
+  printfn "#rows in action table: %d" actionTable.Length; 
+(*
+  printfn "#unique rows in action table: %d" (List.length (Array.foldBack (fun row acc -> insert (Array.to_list row) acc) actionTable [])); 
+  printfn "maximum #different actions per state: %d" (Array.foldBack (fun row acc ->max (List.length (List.foldBack insert (Array.to_list row) [])) acc) actionTable 0); 
+  printfn "average #different actions per state: %d" ((Array.foldBack (fun row acc -> (List.length (List.foldBack insert (Array.to_list row) [])) + acc) actionTable 0) / (Array.length states)); 
+*)
+
+  cprintfn cos "// Implementation file for parser generated by fsyacc";
+  cprintfn cosi "// Signature file for parser generated by fsyacc";
+
+  if (!light = Some(false)) || (!light = None && checkSuffix output ".ml") then
+      cprintfn cos "#light \"off\"";
+      cprintfn cosi "#light \"off\"";
+
+  match !modname with 
+  | None -> ()
+  | Some s -> 
+      match !internal_module with
+      | true ->
+          cprintfn cos "module internal %s" s;
+          cprintfn cosi "module internal %s" s;
+      | false ->
+          cprintfn cos "module %s" s;
+          cprintfn cosi "module %s" s;
+  
+  cprintfn cos "#nowarn \"64\";; // turn off warnings that type variables used in production annotations are instantiated to concrete type";
+
+  for s in !opens do
+      cprintfn cos "open %s" s;
+      cprintfn cosi "open %s" s;
+
+  cprintfn cos "open %s" lexlib;
+  cprintfn cos "open %s.ParseHelpers" parslib;
+  if !compat then 
+      cprintfn cos "open Microsoft.FSharp.Compatibility.OCaml.Parsing";
+
+  cprintfn cos "# %d \"%s\"" pos.pos_lnum pos.pos_fname;
+  cprintfn cos "%s" code;
+  lineCountOutput := !lineCountOutput + code.Replace("\r","").Split([| '\n' |]).Length;
+
+  cprintfn cos "# %d \"%s\"" !lineCountOutput output;
+  // Print the datatype for the tokens
+  cprintfn cos "// This type is the type of tokens accepted by the parser";
+  for out in [cos;cosi] do
+      cprintfn out "type token = ";
+      for id,typ in spec.Tokens do 
+          match typ with
+          | None -> cprintfn out "  | %s" id
+          | Some ty -> cprintfn out "  | %s of (%s)" id ty; 
+
+  // Print the datatype for the token names
+  cprintfn cos "// This type is used to give symbolic names to token indexes, useful for error messages";
+  for out in [cos;cosi] do
+      cprintfn out "type tokenId = ";
+      for id,typ in spec.Tokens do 
+          cprintfn out "    | TOKEN_%s" id;
+      cprintfn out "    | TOKEN_end_of_input";
+      cprintfn out "    | TOKEN_error";
+
+  cprintfn cos "// This type is used to give symbolic names to token indexes, useful for error messages";
+  for out in [cos;cosi] do
+      cprintfn out "type nonTerminalId = ";
+      for nt in nonTerminals do 
+          cprintfn out "    | NONTERM_%s" nt;
+
+  cprintfn cos "";
+  cprintfn cos "// This function maps tokens to integers indexes";
+  cprintfn cos "let tagOfToken (t:token) = ";
+  cprintfn cos "  match t with";
+  spec.Tokens |> List.iteri (fun i (id,typ) -> 
+      cprintfn cos "  | %s %s -> %d " id (match typ with Some _ -> "_" | None -> "") i);
+  cprintfn cosi "/// This function maps integers indexes to symbolic token ids";
+  cprintfn cosi "val tagOfToken: token -> int";
+
+  cprintfn cos "";
+  cprintfn cos "// This function maps integers indexes to symbolic token ids";
+  cprintfn cos "let tokenTagToTokenId (tokenIdx:int) = ";
+  cprintfn cos "  match tokenIdx with";
+  spec.Tokens |> List.iteri (fun i (id,typ) -> 
+      cprintfn cos "  | %d -> TOKEN_%s " i id)
+  cprintfn cos "  | %d -> TOKEN_end_of_input" endOfInputTerminalIdx;
+  cprintfn cos "  | %d -> TOKEN_error" errorTerminalIdx;
+  cprintfn cos "  | _ -> failwith \"tokenTagToTokenId: bad token\""
+
+  cprintfn cosi "";
+  cprintfn cosi "/// This function maps integers indexes to symbolic token ids";
+  cprintfn cosi "val tokenTagToTokenId: int -> tokenId";
+
+  cprintfn cos "";
+  cprintfn cos "/// This function maps production indexes returned in syntax errors to strings representing the non terminal that would be produced by that production";
+  cprintfn cos "let prodIdxToNonTerminal (prodIdx:int) = ";
+  cprintfn cos "  match prodIdx with";
+  prods |> Array.iteri (fun i (nt,ntIdx,syms,code) -> 
+      cprintfn cos "    | %d -> NONTERM_%s " i nt);
+  cprintfn cos "    | _ -> failwith \"prodIdxToNonTerminal: bad production index\""
+
+  cprintfn cosi "";
+  cprintfn cosi "/// This function maps production indexes returned in syntax errors to strings representing the non terminal that would be produced by that production";
+  cprintfn cosi "val prodIdxToNonTerminal: int -> nonTerminalId";
+
+  cprintfn cos "";
+  cprintfn cos "let _fsyacc_endOfInputTag = %d " endOfInputTerminalIdx;
+  cprintfn cos "let _fsyacc_tagOfErrorTerminal = %d" errorTerminalIdx;
+  cprintfn cos "";
+  cprintfn cos "// This function gets the name of a token as a string";
+  cprintfn cos "let token_to_string (t:token) = ";
+  cprintfn cos "  match t with ";
+  spec.Tokens |> List.iteri (fun i (id,typ) -> 
+      cprintfn cos "  | %s %s -> \"%s\" " id (match typ with Some _ -> "_" | None -> "") id);
+
+  cprintfn cosi "";
+  cprintfn cosi "/// This function gets the name of a token as a string";
+  cprintfn cosi "val token_to_string: token -> string";
+
+  cprintfn cos "";
+  cprintfn cos "// This function gets the data carried by a token as an object";
+  cprintfn cos "let _fsyacc_dataOfToken (t:token) = ";
+  cprintfn cos "  match t with ";
+
+  for (id,typ) in spec.Tokens do
+      cprintfn cos "  | %s %s -> %s " 
+        id
+        (match typ with Some _ -> "_fsyacc_x" | None -> "")
+        (match typ with Some _ -> "Microsoft.FSharp.Core.Operators.box _fsyacc_x" | None -> "(null : System.Object)")
+
+  let tychar = "'cty" 
+
+  for (key,_) in spec.Types |> Seq.countBy fst |> Seq.filter (fun (_,n) -> n > 1)  do
+        failwithf "%s is given multiple %%type declarations" key;
+    
+  for (key,_) in spec.Tokens |> Seq.countBy fst |> Seq.filter (fun (_,n) -> n > 1)  do
+        failwithf "%s is given %%token declarations" key
+    
+  let types = Map.ofList spec.Types 
+  let tokens = Map.ofList spec.Tokens 
+  
+  let nStates = states.Length 
+  begin 
+      cprintf cos "let _fsyacc_gotos = [| " ;
+      let numGotoNonTerminals = gotoTable.[0].Length 
+      let gotoIndexes = Array.create numGotoNonTerminals 0 
+      let gotoTableCurrIndex = ref 0 in 
+      for j = 0 to numGotoNonTerminals-1 do  
+          gotoIndexes.[j] <- !gotoTableCurrIndex;
+
+          (* Count the number of entries in the association table. *)
+          let count = ref 0 in 
+          for i = 0 to nStates - 1 do 
+            let goto = gotoTable.[i].[j] 
+            match goto with 
+            | None -> ()
+            | Some _ -> incr count
+   
+          (* Write the head of the table (i.e. the number of entries and the default value) *)
+          gotoTableCurrIndex := !gotoTableCurrIndex + 1;
+          outputCodedUInt16 os !count;
+          outputCodedUInt16 os anyMarker;
+          
+          (* Write the pairs of entries in incremental order by key *)
+          (* This lets us implement the lookup by a binary chop. *)
+          for i = 0 to nStates - 1 do 
+            let goto = gotoTable.[i].[j] 
+            match goto with 
+            | None -> ()
+            | Some n -> 
+                gotoTableCurrIndex := !gotoTableCurrIndex + 1;
+                outputCodedUInt16 os i;
+                outputCodedUInt16 os n;
+      cprintfn cos "|]" ;
+      (* Output offsets into gotos table where the gotos for a particular nonterminal begin *)
+      cprintf cos "let _fsyacc_sparseGotoTableRowOffsets = [|" ;
+      for j = 0 to numGotoNonTerminals-1 do  
+          outputCodedUInt16 os gotoIndexes.[j];
+      cprintfn cos "|]" ;
+  end;
+
+  begin 
+      cprintf cos "let _fsyacc_stateToProdIdxsTableElements = [| " ;
+      let indexes = Array.create states.Length 0 
+      let currIndex = ref 0 
+      for j = 0 to states.Length - 1 do
+          let state = states.[j]
+          indexes.[j] <- !currIndex;
+
+          (* Write the head of the table (i.e. the number of entries) *)
+          outputCodedUInt16 os state.Length;
+          currIndex := !currIndex + state.Length + 1;
+          
+          (* Write the pairs of entries in incremental order by key *)
+          (* This lets us implement the lookup by a binary chop. *)
+          for prodIdx in state do
+                outputCodedUInt16 os prodIdx;
+      cprintfn cos "|]" ;
+      (* Output offsets into gotos table where the gotos for a particular nonterminal begin *)
+      cprintf cos "let _fsyacc_stateToProdIdxsTableRowOffsets = [|" ;
+      for idx in indexes do 
+          outputCodedUInt16 os idx;
+      cprintfn cos "|]" ;
+  end;
+
+  begin 
+    let numActionRows = (Array.length actionTable) 
+    let maxActionColumns = Array.length actionTable.[0] 
+    cprintfn cos "let _fsyacc_action_rows = %d" numActionRows;
+    cprintf cos "let _fsyacc_actionTableElements = [|" ;
+    let actionIndexes = Array.create numActionRows 0 
+    
+    let actionTableCurrIndex = ref 0 
+    for i = 0 to nStates-1 do 
+        actionIndexes.[i] <- !actionTableCurrIndex;
+        let actions = actionTable.[i] 
+        let terminalsByAction = new Dictionary<_,int list>(10) 
+        let countPerAction = new Dictionary<_,_>(10) 
+        for terminal = 0 to actions.Length - 1 do  
+              let action = snd actions.[terminal] 
+              if terminalsByAction.ContainsKey action then 
+                  terminalsByAction.[action] <- terminal :: terminalsByAction.[action] ;
+              else
+                  terminalsByAction.[action] <- [terminal];
+              if countPerAction.ContainsKey action then 
+                countPerAction.[action] <- countPerAction.[action]+1
+              else 
+                countPerAction.[action] <- 1
+
+        let mostCommonAction = 
+            let mostCommon = ref Error 
+            let max = ref 0 
+            for (KeyValue(x,y)) in countPerAction do 
+                if y > !max then (mostCommon := x; max := y)
+            !mostCommon 
+
+        (* Count the number of entries in the association table. *)
+        let count = ref 0 
+        for (KeyValue(action,terminals)) in terminalsByAction do 
+            for terminals  in terminals do 
+               if action <> mostCommonAction then  
+                   incr count;
+        
+        (* Write the head of the table (i.e. the number of entries and the default value) *)
+        actionTableCurrIndex := !actionTableCurrIndex + 1;
+        outputCodedUInt16 os !count;
+        outputCodedUInt16 os (actionCoding mostCommonAction);
+        
+        (* Write the pairs of entries in incremental order by key *)
+        (* This lets us implement the lookup by a binary chop. *)
+        for terminal = 0 to Array.length actions-1 do  
+            let action = snd actions.[terminal] in 
+            if action <> mostCommonAction then  (
+                actionTableCurrIndex := !actionTableCurrIndex + 1;
+                outputCodedUInt16 os terminal;
+                outputCodedUInt16 os (actionCoding action);
+            );
+    cprintfn cos "|]" ;
+    (* Output offsets into actions table where the actions for a particular nonterminal begin *)
+    cprintf cos "let _fsyacc_actionTableRowOffsets = [|" ;
+    for j = 0 to numActionRows-1 do  
+        cprintf cos "%a" outputCodedUInt16 actionIndexes.[j];
+    cprintfn cos "|]" ;
+
+  end;
+  begin 
+      cprintf cos "let _fsyacc_reductionSymbolCounts = [|" ;
+      for nt,ntIdx,syms,code in prods do 
+          cprintf cos "%a" outputCodedUInt16 (List.length syms);
+      cprintfn cos "|]" ;
+  end;
+  begin 
+      cprintf cos "let _fsyacc_productionToNonTerminalTable = [|" ;
+      for nt,ntIdx,syms,code in prods do 
+          cprintf cos "%a" outputCodedUInt16 ntIdx;
+      cprintfn cos "|]" ;
+  end;
+  begin 
+      cprintf cos "let _fsyacc_immediateActions = [|" ;
+      for prodIdx in immediateActionTable do 
+          match prodIdx with
+            | None     -> cprintf cos "%a" outputCodedUInt16 anyMarker (* NONE REP *)
+            | Some act -> cprintf cos "%a" outputCodedUInt16 (actionCoding act)
+      cprintfn cos "|]" ;
+  end;
+  
+  let getType nt = if types.ContainsKey nt then  types.[nt] else "'"+nt 
+  begin 
+      cprintf cos "let _fsyacc_reductions ()  =" ;
+      cprintfn cos "    [| " ;
+      for nt,ntIdx,syms,code in prods do 
+          cprintfn cos "# %d \"%s\"" !lineCountOutput output;
+          cprintfn cos "        (fun (parseState : %s.IParseState) ->"  parslib
+          if !compat then 
+              cprintfn cos "            Parsing.set_parse_state parseState;"
+          syms |> List.iteri (fun i sym -> 
+              let tyopt = 
+                  match sym with
+                  | Terminal t -> 
+                      if tokens.ContainsKey t then 
+                        tokens.[t]
+                      else None
+                  | NonTerminal nt -> Some (getType nt) 
+              match tyopt with 
+              | Some ty -> cprintfn cos "            let _%d = (let data = parseState.GetInput(%d) in (Microsoft.FSharp.Core.Operators.unbox data : %s)) in" (i+1) (i+1) ty
+              | None -> ())
+          cprintfn cos "            Microsoft.FSharp.Core.Operators.box" 
+          cprintfn cos "                (";
+          cprintfn cos "                   (";
+          match code with 
+          | Some (_,pos) -> cprintfn cos "# %d \"%s\"" pos.pos_lnum pos.pos_fname
+          | None -> ()
+          match code with 
+          | Some (code,_) -> 
+              let dollar = ref false in 
+              let c = code |> String.collect (fun c -> 
+                  if not !dollar && c = '$' then (dollar := true; "")
+                  elif !dollar && c >= '0' && c <= '9' then (dollar := false; "_"+new System.String(c,1))
+                  elif !dollar then (dollar := false; "$"+new System.String(c,1))
+                  else new System.String(c,1))
+              let lines = c.Split([| '\r'; '\n' |], System.StringSplitOptions.RemoveEmptyEntries);
+              for line in lines do 
+                  cprintfn cos "                     %s" line;
+              if !dollar then os.Write '$'
+          | None -> 
+              cprintfn cos "                      raise (%s.Accept(Microsoft.FSharp.Core.Operators.box _1))" parslib
+          cprintfn cos "                   )";
+          // Place the line count back for the type constraint
+          match code with 
+          | Some (_,pos) -> cprintfn cos "# %d \"%s\"" pos.pos_lnum pos.pos_fname
+          | None -> ()
+          cprintfn cos "                 : %s));" (if types.ContainsKey nt then  types.[nt] else "'"+nt);
+      done;
+      cprintfn cos "|]" ;
+  end;
+  cprintfn cos "# %d \"%s\"" !lineCountOutput output;
+  cprintfn cos "let tables () : %s.Tables<_> = " parslib
+  cprintfn cos "  { reductions= _fsyacc_reductions ();"
+  cprintfn cos "    endOfInputTag = _fsyacc_endOfInputTag;"
+  cprintfn cos "    tagOfToken = tagOfToken;"
+  cprintfn cos "    dataOfToken = _fsyacc_dataOfToken; "
+  cprintfn cos "    actionTableElements = _fsyacc_actionTableElements;"
+  cprintfn cos "    actionTableRowOffsets = _fsyacc_actionTableRowOffsets;"
+  cprintfn cos "    stateToProdIdxsTableElements = _fsyacc_stateToProdIdxsTableElements;"
+  cprintfn cos "    stateToProdIdxsTableRowOffsets = _fsyacc_stateToProdIdxsTableRowOffsets;"
+  cprintfn cos "    reductionSymbolCounts = _fsyacc_reductionSymbolCounts;"
+  cprintfn cos "    immediateActions = _fsyacc_immediateActions;"
+  cprintfn cos "    gotos = _fsyacc_gotos;"
+  cprintfn cos "    sparseGotoTableRowOffsets = _fsyacc_sparseGotoTableRowOffsets;"
+  cprintfn cos "    tagOfErrorTerminal = _fsyacc_tagOfErrorTerminal;"
+  cprintfn cos "    parseError = (fun (ctxt:%s.ParseErrorContext<_>) -> " parslib
+  cprintfn cos "                              match parse_error_rich with "
+  cprintfn cos "                              | Some f -> f ctxt"
+  cprintfn cos "                              | None -> parse_error ctxt.Message);"
+  
+  cprintfn cos "    numTerminals = %d;" (Array.length actionTable.[0]);
+  cprintfn cos "    productionToNonTerminalTable = _fsyacc_productionToNonTerminalTable  }"
+  cprintfn cos "let engine lexer lexbuf startState = (tables ()).Interpret(lexer, lexbuf, startState)"                                                                                                         
+
+  for (id,startState) in List.zip spec.StartSymbols startStates do
+        if not (types.ContainsKey id) then 
+          failwith ("a %type declaration is required for for start token "+id);
+        let ty = types.[id] in 
+        cprintfn cos "let %s lexer lexbuf : %s =" id ty;
+        cprintfn cos "    Microsoft.FSharp.Core.Operators.unbox ((tables ()).Interpret(lexer, lexbuf, %d))" startState
+
+  for id in spec.StartSymbols do
+      if not (types.ContainsKey id) then 
+        failwith ("a %type declaration is required for start token "+id);
+      let ty = types.[id] in 
+      cprintfn cosi "val %s : (%s.LexBuffer<%s> -> token) -> %s.LexBuffer<%s> -> (%s) " id lexlib tychar lexlib tychar ty;
+
+  logf (fun oso -> oso.Close())
+
+let _ = 
+    try main()
+    with e -> 
+      printf "FSYACC: error FSY000: %s" (match e with Failure s -> s | e -> e.Message);
+      exit 1
+
--- fsharp-3.1.1.26+dfsg2.orig/FsYacc/fsyaccast.fs
+++ fsharp-3.1.1.26+dfsg2/FsYacc/fsyaccast.fs
@@ -1,965 +1,965 @@
-// (c) Microsoft Corporation 2005-2007.
-
-module internal FSharp.PowerPack.FsYacc.AST
-
-#nowarn "62" // This construct is for ML compatibility.
-
-
-open System
-open System.Collections.Generic
-open Printf
-open Microsoft.FSharp.Collections
-open Internal.Utilities
-open Internal.Utilities.Text.Lexing
-
-/// An active pattern that should be in the F# standard library
-let (|KeyValue|) (kvp:KeyValuePair<_,_>) = kvp.Key,kvp.Value
-
-
-type Identifier = string
-type Code = string * Position
-
-type ParserSpec= 
-    { Header         : Code;
-      Tokens         : (Identifier * string option) list;
-      Types          : (Identifier * string) list;
-      Associativities: (Identifier * Associativity) list list;
-      StartSymbols   : Identifier list;
-      Rules          : (Identifier * Rule list) list }
-      
-and Rule = Rule of Identifier list * Identifier option * Code option
-and Associativity = LeftAssoc | RightAssoc | NonAssoc
-
-type Terminal = string
-type NonTerminal = string
-type Symbol = Terminal of Terminal | NonTerminal of NonTerminal
-type Symbols = Symbol list
-
-
-//---------------------------------------------------------------------
-// Output Raw Parser Spec AST
-
-let StringOfSym sym = match sym with Terminal s -> "'" ^ s ^ "'" | NonTerminal s -> s
-
-let OutputSym os sym = fprintf os "%s" (StringOfSym sym)
-
-let OutputSyms os syms =
-    fprintf os "%s" (String.Join(" ",Array.map StringOfSym syms))
-
-let OutputTerminalSet os (tset:string seq)  =
-    fprintf os "%s" (String.Join(";", tset |> Seq.toArray))
-
-let OutputAssoc os p = 
-    match p with 
-    | LeftAssoc -> fprintf os "left"
-    | RightAssoc -> fprintf os "right"
-    | NonAssoc -> fprintf os "nonassoc"
-
-
-//---------------------------------------------------------------------
-// PreProcess Raw Parser Spec AST
-
-type PrecedenceInfo = 
-    | ExplicitPrec of Associativity * int 
-    | NoPrecedence
-      
-type Production = Production of NonTerminal * PrecedenceInfo * Symbols * Code option
-
-type ProcessedParserSpec = 
-    { Terminals: (Terminal * PrecedenceInfo) list;
-      NonTerminals: NonTerminal list;
-      Productions: Production list;
-      StartSymbols: NonTerminal list }
-
-
-let ProcessParserSpecAst (spec: ParserSpec) = 
-    let explicitPrecInfo = 
-        spec.Associativities 
-        |> List.mapi (fun n precSpecs -> precSpecs |> List.map (fun (precSym, assoc) -> precSym,ExplicitPrec (assoc, 10000 - n)))
-        |> List.concat
-    
-    for (key,_) in explicitPrecInfo |> Seq.countBy fst |> Seq.filter (fun (_,n) -> n > 1)  do
-        failwithf "%s is given two associativities" key
-    
-    let explicitPrecInfo = 
-        explicitPrecInfo |> Map.ofList
-
-    let implicitSymPrecInfo = NoPrecedence
-    let terminals = List.map fst spec.Tokens @ ["error"]in 
-    let terminalSet = Set.ofList terminals
-    let IsTerminal z = terminalSet.Contains(z)
-    let prec_of_terminal sym implicitPrecInfo = 
-       if explicitPrecInfo.ContainsKey(sym) then explicitPrecInfo.[sym]
-       else match implicitPrecInfo with Some x -> x | None -> implicitSymPrecInfo
-       
-    let mkSym s = if IsTerminal s then Terminal s else NonTerminal s
-    let prods =  
-        spec.Rules |> List.mapi (fun i (nonterm,rules) -> 
-            rules |> List.mapi (fun j (Rule(syms,precsym,code)) -> 
-                let precInfo = 
-                    let precsym = List.foldBack (fun x acc -> match acc with Some _ -> acc | None -> match x with z when IsTerminal z -> Some z | _ -> acc) syms precsym
-                    let implicitPrecInfo = NoPrecedence
-                    match precsym with 
-                    | None -> implicitPrecInfo 
-                    | Some sym -> if explicitPrecInfo.ContainsKey(sym) then explicitPrecInfo.[sym] else implicitPrecInfo
-                Production(nonterm, precInfo, List.map mkSym syms, code)))
-         |> List.concat
-    let nonTerminals = List.map fst spec.Rules
-    let nonTerminalSet = Set.ofList nonTerminals
-    let checkNonTerminal nt =  
-        if nt <> "error" && not (nonTerminalSet.Contains(nt)) then 
-            failwith (sprintf "NonTerminal '%s' has no productions" nt)
-
-    for (Production(nt,_,syms,_)) in prods do
-        for sym in syms do 
-           match sym with 
-           | NonTerminal nt -> 
-               checkNonTerminal nt 
-           | Terminal t ->  
-               if not (IsTerminal t) then failwith (sprintf "token %s is not declared" t)
-           
-    if spec.StartSymbols= [] then (failwith "at least one %start declaration is required\n");
-
-    for (nt,_) in spec.Types do 
-        checkNonTerminal nt;
-
-    let terminals = terminals |> List.map (fun t -> (t,prec_of_terminal t None)) 
-
-    { Terminals=terminals;
-      NonTerminals=nonTerminals;
-      Productions=prods;
-      StartSymbols=spec.StartSymbols }
-
-
-//-------------------------------------------------
-// Process LALR(1) grammars to tables
-
-type ProductionIndex = int
-type ProdictionDotIndex = int
-
-/// Represent (ProductionIndex,ProdictionDotIndex) as one integer 
-type Item0 = uint32  
-
-let mkItem0 (prodIdx,dotIdx) : Item0 = (uint32 prodIdx <<< 16) ||| uint32 dotIdx
-let prodIdx_of_item0 (item0:Item0) = int32 (item0 >>> 16)
-let dotIdx_of_item0 (item0:Item0) = int32 (item0 &&& 0xFFFFu)
-
-/// Part of the output of CompilerLalrParserSpec
-type Action = 
-  | Shift of int
-  | Reduce of ProductionIndex
-  | Accept
-  | Error
-    
-let outputPrecInfo os p = 
-    match p with 
-    | ExplicitPrec (assoc,n) -> fprintf os "explicit %a %d" OutputAssoc assoc n
-    | NoPrecedence  -> fprintf os "noprec"
-
-
-/// LR(0) kernels
-type Kernel = Set<Item0>
-
-/// Indexes of LR(0) kernels in the KernelTable
-type KernelIdx = int
-
-/// Indexes in the TerminalTable and NonTerminalTable
-type TerminalIndex = int
-type NonTerminalIndex = int
-
-/// Representation of Symbols.
-/// Ideally would be declared as 
-///    type SymbolIndex = PTerminal of TerminalIndex | PNonTerminal of NonTerminalIndex
-/// but for performance reasons we embed as a simple integer (saves ~10%)
-///
-/// We use an active pattern to reverse the embedding.
-type SymbolIndex = int
-let PTerminal(i:TerminalIndex) : SymbolIndex = -i-1
-let PNonTerminal(i:NonTerminalIndex) : SymbolIndex = i
-let (|PTerminal|PNonTerminal|) x = if x < 0 then PTerminal (-(x+1)) else PNonTerminal x
-
-type SymbolIndexes = SymbolIndex list
-
-/// Indexes in the LookaheadTable, SpontaneousTable, PropagateTable
-/// Embed in a single integer, since these are faster
-/// keys for the dictionary hash tables
-///
-/// Logically:
-///
-///   type KernelItemIndex = KernelItemIdx of KernelIdx * Item0
-type KernelItemIndex = int64
-let KernelItemIdx (i1,i2) = ((int64 i1) <<< 32) ||| int64 i2
-
-
-/// Indexes into the memoizing table for the Goto computations
-/// Embed in a single integer, since these are faster
-/// keys for the dictionary hash tables
-///
-/// Logically:
-///
-///   type GotoItemIndex = GotoItemIdx of KernelIdx * SymbolIndex
-type GotoItemIndex = uint64
-let GotoItemIdx (i1:KernelIdx,i2:SymbolIndex) = (uint64 (uint32 i1) <<< 32) ||| uint64 (uint32 i2)
-let (|GotoItemIdx|) (i64:uint64) = int32 ((i64 >>> 32) &&& 0xFFFFFFFFUL), int32 (i64 &&& 0xFFFFFFFFUL)
-
-/// Create a work list and loop until it is exhausted, calling a worker function for
-/// each element. Pass a function to queue additional work on the work list 
-/// to the worker function
-let ProcessWorkList start f =
-    let work = ref (start : 'a list)
-    let queueWork = (fun x -> work := x :: !work)
-    let rec loop() = 
-        match !work with 
-        | [] -> ()
-        | x::t -> 
-            work := t; 
-            f queueWork x;
-            loop()
-    loop()
-
-/// A standard utility to compute a least fixed point of a set under a generative computation
-let LeastFixedPoint f set = 
-    let acc = ref set
-    ProcessWorkList (Set.toList set) (fun queueWork item ->
-          f(item) |> List.iter (fun i2 -> if not (Set.contains i2 !acc) then (acc := Set.add i2 !acc; queueWork i2)) )
-    !acc
-
-/// A general standard memoization utility. Be sure to apply to only one (function) argument to build the
-/// residue function!
-let Memoize f = 
-    let t = new Dictionary<_,_>(1000)
-    fun x -> 
-        let ok,v = t.TryGetValue(x) 
-        if ok then v else let res = f x in t.[x] <- res; res 
-
-/// A standard utility to create a dictionary from a list of pairs
-let CreateDictionary xs = 
-    let dict = new Dictionary<_,_>()
-    for x,y in xs do dict.Add(x,y)
-    dict
-
-/// Allocate indexes for each non-terminal
-type NonTerminalTable(nonTerminals:NonTerminal list) = 
-    let nonterminalsWithIdxs = List.mapi (fun (i:NonTerminalIndex) n -> (i,n)) nonTerminals
-    let nonterminalIdxs = List.map fst nonterminalsWithIdxs
-    let a = Array.ofList nonTerminals
-    let b = CreateDictionary [ for i,x in nonterminalsWithIdxs -> x,i ];
-    member table.OfIndex(i) = a.[i]
-    member table.ToIndex(i) = b.[i]
-    member table.Indexes = nonterminalIdxs
-
-/// Allocate indexes for each terminal
-type TerminalTable(terminals:(Terminal * PrecedenceInfo) list) = 
-    let terminalsWithIdxs = List.mapi (fun i (t,_) -> (i,t)) terminals
-    let terminalIdxs = List.map fst terminalsWithIdxs
-    let a = Array.ofList (List.map fst terminals)
-    let b = Array.ofList (List.map snd terminals)
-    let c = CreateDictionary [ for i,x in terminalsWithIdxs -> x,i ]
-
-    member table.OfIndex(i) = a.[i]
-    member table.PrecInfoOfIndex(i) = b.[i]
-    member table.ToIndex(i) = c.[i]
-    member table.Indexes = terminalIdxs
-
-/// Allocate indexes for each production
-type ProductionTable(ntTab:NonTerminalTable, termTab:TerminalTable, nonTerminals:string list, prods: Production list) =
-    let prodsWithIdxs = List.mapi (fun i n -> (i,n)) prods
-    let a =  
-        prodsWithIdxs
-        |> List.map(fun (_,Production(_,_,syms,_)) -> 
-              syms 
-              |> Array.ofList  
-              |> Array.map (function 
-                            | Terminal t -> PTerminal (termTab.ToIndex t) 
-                            | NonTerminal nt -> PNonTerminal (ntTab.ToIndex nt )) )
-        |> Array.ofList
-    let b = Array.ofList (List.map (fun (_,Production(nt,_,_,_)) -> ntTab.ToIndex nt) prodsWithIdxs)
-    let c = Array.ofList (List.map (fun (_,Production(_,prec,_,_)) -> prec) prodsWithIdxs)
-    let productions = 
-        nonTerminals
-        |> List.map(fun nt -> (ntTab.ToIndex nt, List.choose (fun (i,Production(nt2,prec,syms,_)) -> if nt2=nt then Some i else None) prodsWithIdxs))
-        |> CreateDictionary
-
-    member prodTab.Symbols(i) = a.[i]
-    member prodTab.NonTerminal(i) = b.[i]
-    member prodTab.Precedence(i) = c.[i]
-    member prodTab.Symbol i n = 
-        let syms = prodTab.Symbols i
-        if n >= syms.Length then None else Some (syms.[n])
-    member prodTab.Productions = productions
-
-/// A mutable table maping kernels to sets of lookahead tokens
-type LookaheadTable() = 
-    let t = new Dictionary<KernelItemIndex,Set<TerminalIndex>>()
-    member table.Add(x,y) = 
-        let prev = if t.ContainsKey(x) then t.[x] else Set.empty 
-        t.[x] <- prev.Add(y)
-    member table.Contains(x,y) = t.ContainsKey(x) && t.[x].Contains(y)
-    member table.GetLookaheads(idx:KernelItemIndex) = 
-        let ok,v = t.TryGetValue(idx)  
-        if ok then v else Set.empty
-    member table.Count = t |> Seq.fold(fun acc (KeyValue(_,v)) -> v.Count+acc) 0
-
-/// A mutable table giving an index to each LR(0) kernel. Kernels are referred to only by index.
-type KernelTable(kernels) =
-    // Give an index to each LR(0) kernel, and from now on refer to them only by index 
-    // Also develop "kernelItemIdx" to refer to individual items within a kernel 
-    let kernelsAndIdxs = List.mapi (fun i x -> (i,x)) kernels
-    let kernelIdxs = List.map fst kernelsAndIdxs
-    let toIdxMap = Map.ofList [ for i,x in kernelsAndIdxs -> x,i ]
-    let ofIdxMap = Array.ofList kernels
-    member t.Indexes = kernelIdxs
-    member t.Index(kernel) = toIdxMap.[kernel]
-    member t.Kernel(i) = ofIdxMap.[i]
-
-/// Hold the results of cpmuting the LALR(1) closure of an LR(0) kernel
-type Closure1Table() = 
-    let t = new Dictionary<Item0,HashSet<TerminalIndex>>()
-    member table.Add(a,b) = 
-        if not (t.ContainsKey(a)) then t.[a] <- new HashSet<_>(HashIdentity.Structural)
-        t.[a].Add(b)
-    member table.Count  = t.Count
-    member table.IEnumerable = (t :> seq<_>)
-    member table.Contains(a,b) = t.ContainsKey(a) && t.[a].Contains(b)
-
-/// A mutable table giving a lookahead set Set<Terminal> for each kernel. The terminals represent the
-/// "spontaneous" items for the kernel. TODO: document this more w.r.t. the Dragon book.
-type SpontaneousTable() = 
-    let t = new Dictionary<KernelItemIndex,HashSet<TerminalIndex>>()
-    member table.Add(a,b) = 
-        if not (t.ContainsKey(a)) then t.[a] <- new HashSet<_>(HashIdentity.Structural)
-        t.[a].Add(b)
-    member table.Count  = t.Count
-    member table.IEnumerable = (t :> seq<_>)
-
-/// A mutable table giving a Set<KernelItemIndex> for each kernel. The kernels represent the
-/// "propagate" items for the kernel. TODO: document this more w.r.t. the Dragon book.
-type PropagateTable() = 
-    let t = new Dictionary<KernelItemIndex,HashSet<KernelItemIndex>>()
-    member table.Add(a,b) = 
-        if not (t.ContainsKey(a)) then t.[a] <- new HashSet<KernelItemIndex>(HashIdentity.Structural)
-        t.[a].Add(b)
-    member table.Item 
-      with get(a) = 
-        let ok,v = t.TryGetValue(a) 
-        if ok then v :> seq<_> else Seq.empty
-    member table.Count  = t.Count
-
-
-/// Compile a pre-processed LALR parser spec to tables following the Dragon book algorithm
-let CompilerLalrParserSpec logf (spec : ProcessedParserSpec) =
-    let stopWatch = new System.Diagnostics.Stopwatch()
-    let reportTime() = printfn "time: %A" stopWatch.Elapsed; stopWatch.Reset(); stopWatch.Start()
-    stopWatch.Start()
-
-    // Augment the grammar 
-    let fakeStartNonTerminals = spec.StartSymbols |> List.map(fun nt -> "_start"^nt) 
-    let nonTerminals = fakeStartNonTerminals@spec.NonTerminals
-    let endOfInputTerminal = "$$"
-    let dummyLookahead = "#"
-    let dummyPrec = NoPrecedence
-    let terminals = spec.Terminals @ [(dummyLookahead,dummyPrec); (endOfInputTerminal,dummyPrec)]
-    let prods = List.map2 (fun a b -> Production(a, dummyPrec,[NonTerminal b],None)) fakeStartNonTerminals spec.StartSymbols @ spec.Productions
-    let startNonTerminalIdx_to_prodIdx (i:int) = i
-
-    // Build indexed tables 
-    let ntTab = NonTerminalTable(nonTerminals)
-    let termTab = TerminalTable(terminals)
-    let prodTab = ProductionTable(ntTab,termTab,nonTerminals,prods)
-    let dummyLookaheadIdx = termTab.ToIndex dummyLookahead
-    let endOfInputTerminalIdx = termTab.ToIndex endOfInputTerminal
-
-
-    // printf "terminalPrecInfo(ELSE) = %a\n" outputPrecInfo (termTab.PrecInfoOfIndex (termTab.ToIndex "ELSE"));
-
-    let errorTerminalIdx = termTab.ToIndex "error"
-
-    // Compute the FIRST function
-    printf  "computing first function..."; stdout.Flush();
-
-    let computedFirstTable = 
-        let seed = 
-            Map.ofList
-             [ for term in termTab.Indexes do yield (PTerminal(term),Set.singleton (Some term))
-               for nonTerm in ntTab.Indexes do 
-                  yield 
-                    (PNonTerminal nonTerm, 
-                     List.foldBack 
-                       (fun prodIdx acc -> match prodTab.Symbol prodIdx 0 with None -> Set.add None acc | Some _ -> acc) 
-                       prodTab.Productions.[nonTerm] 
-                       Set.empty) ]
-                 
-        let add changed ss (x,y) = 
-            let s = Map.find x ss
-            if Set.contains y s then ss 
-            else (changed := true; Map.add x (Set.add y s) ss)
-
-        let oneRound (ss:Map<_,_>) = 
-            let changed = ref false
-            let frontier = 
-                let res = ref []
-                for nonTermX in ntTab.Indexes do 
-                    for prodIdx in prodTab.Productions.[nonTermX] do
-                        let rhs = Array.toList (prodTab.Symbols prodIdx)
-                        let rec place l =
-                            match l with
-                            | (yi::t) -> 
-                                res := 
-                                   List.choose 
-                                     (function None -> None | Some a -> Some (PNonTerminal nonTermX,Some a)) 
-                                     (Set.toList ss.[yi]) 
-                                   @ !res;
-                                if ss.[yi].Contains(None) then place t;
-                            | [] -> 
-                                res := (PNonTerminal nonTermX,None) :: !res
-                        place rhs
-                !res
-            let ss' = List.fold (add changed) ss frontier
-            !changed, ss'
-
-        let rec loop ss = 
-            let changed, ss' = oneRound ss
-            if changed then loop ss' else ss'
-        loop seed 
-            
-      
-    /// Compute the first set of the given sequence of non-terminals. If any of the non-terminals
-    /// have an empty token in the first set then we have to iterate through those. 
-    let ComputeFirstSetOfTokenList =
-        Memoize (fun (str,term) -> 
-            let acc = new System.Collections.Generic.List<_>()
-            let rec add l = 
-                match l with 
-                | [] -> acc.Add(term)
-                | sym::moreSyms -> 
-                    let firstSetOfSym = computedFirstTable.[sym]
-                    firstSetOfSym |> Set.iter (function None -> () | Some v -> acc.Add(v)) 
-                    if firstSetOfSym.Contains(None) then add moreSyms 
-            add str;
-            Set.ofSeq acc)
-    
-    // (int,int) representation of LR(0) items 
-    let prodIdx_to_item0 idx = mkItem0(idx,0) 
-    let prec_of_item0 item0 = prodTab.Precedence (prodIdx_of_item0 item0)
-    let ntIdx_of_item0 item0 = prodTab.NonTerminal (prodIdx_of_item0 item0)
-
-    let lsyms_of_item0 item0 = 
-        let prodIdx = prodIdx_of_item0 item0
-        let dotIdx = dotIdx_of_item0 item0
-        let syms = prodTab.Symbols prodIdx
-        syms.[..dotIdx-1]
-
-    let rsyms_of_item0 item0 = 
-        let prodIdx = prodIdx_of_item0 item0
-        let dotIdx = dotIdx_of_item0 item0
-        let syms = prodTab.Symbols prodIdx
-        syms.[dotIdx..]
-
-    let rsym_of_item0 item0 = 
-        let prodIdx = prodIdx_of_item0 item0
-        let dotIdx = dotIdx_of_item0 item0
-        prodTab.Symbol prodIdx dotIdx
-
-    let advance_of_item0 item0 = 
-        let prodIdx = prodIdx_of_item0 item0
-        let dotIdx = dotIdx_of_item0 item0
-        mkItem0(prodIdx,dotIdx+1)
-    let fakeStartNonTerminalsSet = Set.ofList (fakeStartNonTerminals |> List.map ntTab.ToIndex)
-
-    let IsStartItem item0 = fakeStartNonTerminalsSet.Contains(ntIdx_of_item0 item0)
-    let IsKernelItem item0 = (IsStartItem item0 || dotIdx_of_item0 item0 <> 0)
-
-    let StringOfSym sym = match sym with PTerminal s -> "'" ^ termTab.OfIndex s ^ "'" | PNonTerminal s -> ntTab.OfIndex s
-
-    let OutputSym os sym = fprintf os "%s" (StringOfSym sym)
-
-    let OutputSyms os syms =
-        fprintf os "%s" (String.Join(" ",Array.map StringOfSym syms))
-
-    // Print items and other stuff 
-    let OutputItem0 os item0 =
-        fprintf os "    %s -> %a . %a" (ntTab.OfIndex (ntIdx_of_item0 item0)) (* outputPrecInfo precInfo *) OutputSyms (lsyms_of_item0 item0) OutputSyms (rsyms_of_item0 item0) 
-        
-    let OutputItem0Set os s = 
-        Set.iter (fun item -> fprintf os "%a\n" OutputItem0 item) s
-
-    let OutputFirstSet os m = 
-        Set.iter (function None ->  fprintf os "<empty>" | Some x -> fprintf os "  term %s\n" x) m
-
-    let OutputFirstMap os m = 
-        Map.iter (fun x y -> fprintf os "first '%a' = \n%a\n" OutputSym x OutputFirstSet y) m
-
-    let OutputAction os m = 
-        match m with 
-        | Shift n -> fprintf os "  shift %d" n 
-        | Reduce prodIdx ->  fprintf os "  reduce %s --> %a" (ntTab.OfIndex (prodTab.NonTerminal prodIdx)) OutputSyms (prodTab.Symbols prodIdx)
-        | Error ->  fprintf os "  error"
-        | Accept -> fprintf os "  accept" 
-    
-    let OutputActions os m = 
-        Array.iteri (fun i (prec,action) -> let term = termTab.OfIndex i in fprintf os "    action '%s' (%a): %a\n" term outputPrecInfo prec OutputAction action) m
-
-    let OutputActionTable os m = 
-        Array.iteri (fun i n -> fprintf os "state %d:\n%a\n" i OutputActions n) m
-
-    let OutputImmediateActions os m = 
-        match m with 
-        | None -> fprintf os "<none>"
-        | Some a -> OutputAction os a
-    
-    let OutputGotos os m = 
-        Array.iteri (fun ntIdx s -> let nonterm = ntTab.OfIndex ntIdx in match s with Some st -> fprintf os "    goto %s: %d\n" nonterm st | None -> ()) m
-    
-    let OutputCombined os m = 
-        Array.iteri (fun i (a,b,c,d) -> fprintf os "state %d:\n  items:\n%a\n  actions:\n%a\n  immediate action: %a\n gotos:\n%a\n" i OutputItem0Set a OutputActions b OutputImmediateActions c OutputGotos d) m
-    
-    let OutputLalrTables os (prods,states, startStates,actionTable,immediateActionTable,gotoTable,endOfInputTerminalIdx,errorTerminalIdx) = 
-        let combined = Array.ofList (List.map2 (fun x (y,(z,w)) -> x,y,z,w) (Array.toList states) (List.zip (Array.toList actionTable) (List.zip (Array.toList immediateActionTable) (Array.toList gotoTable))))
-        fprintfn os "------------------------";
-        fprintfn os "states = ";
-        fprintfn os "%a" OutputCombined combined;
-        fprintfn os "startStates = %s" (String.Join(";",Array.ofList (List.map string startStates)));
-        fprintfn os "------------------------"
-
-
-    // Closure of LR(0) nonTerminals, items etc 
-    let ComputeClosure0NonTerminal = 
-        Memoize (fun nt -> 
-            let seed = (List.foldBack (prodIdx_to_item0 >> Set.add) prodTab.Productions.[nt] Set.empty)
-            LeastFixedPoint 
-                (fun item0 -> 
-                   match rsym_of_item0 item0 with
-                   | None -> []
-                   | Some(PNonTerminal ntB) ->  List.map prodIdx_to_item0 prodTab.Productions.[ntB]
-                   | Some(PTerminal _) -> [])
-                seed)
-
-    // Close a symbol under epsilon moves
-    let ComputeClosure0Symbol rsym acc = 
-        match rsym with
-        | Some (PNonTerminal nt) -> Set.union (ComputeClosure0NonTerminal nt) acc
-        | _ -> acc
-
-    // Close a set under epsilon moves
-    let ComputeClosure0 iset = 
-        Set.fold (fun acc x -> ComputeClosure0Symbol (rsym_of_item0 x) acc) iset iset 
-
-    // Right symbols after closing under epsilon moves
-    let RelevantSymbolsOfKernel kernel =
-        let kernelClosure0 = ComputeClosure0 kernel
-        Set.fold (fun acc x -> Option.fold (fun acc x -> Set.add x acc) acc (rsym_of_item0 x)) Set.empty kernelClosure0 
-
-    // Goto set of a kernel of LR(0) nonTerminals, items etc 
-    // Input is kernel, output is kernel
-    let ComputeGotosOfKernel iset sym = 
-        let isetClosure = ComputeClosure0 iset
-        let acc = new System.Collections.Generic.List<_>(10)
-        isetClosure |> Set.iter (fun item0 -> 
-              match rsym_of_item0 item0 with 
-              | Some sym2 when sym = sym2 -> acc.Add(advance_of_item0 item0) 
-              | _ -> ()) 
-        Set.ofSeq acc
-    
-    // Build the full set of LR(0) kernels 
-    reportTime(); printf "building kernels..."; stdout.Flush();
-    let startItems = List.mapi (fun i _ -> prodIdx_to_item0 (startNonTerminalIdx_to_prodIdx i)) fakeStartNonTerminals
-    let startKernels = List.map Set.singleton startItems
-    let kernels = 
-
-        /// We use a set-of-sets here. F# sets support structural comparison but at the time of writing
-        /// did not structural hashing. 
-        let acc = ref Set.empty
-        ProcessWorkList startKernels (fun addToWorkList kernel -> 
-            if not ((!acc).Contains(kernel)) then
-                acc := (!acc).Add(kernel);
-                for csym in RelevantSymbolsOfKernel kernel do 
-                    let gotoKernel = ComputeGotosOfKernel kernel csym 
-                    assert (gotoKernel.Count > 0)
-                    addToWorkList gotoKernel )
-                    
-        !acc |> Seq.toList |> List.map (Set.filter IsKernelItem)
-    
-    reportTime(); printf "building kernel table..."; stdout.Flush();
-    // Give an index to each LR(0) kernel, and from now on refer to them only by index 
-    let kernelTab = new KernelTable(kernels)
-    let startKernelIdxs = List.map kernelTab.Index startKernels
-    let startKernelItemIdxs = List.map2 (fun a b -> KernelItemIdx(a,b)) startKernelIdxs startItems
-
-    let outputKernelItemIdx os (kernelIdx,item0)  =
-        fprintf os "kernel %d, item %a" kernelIdx OutputItem0 item0
-
-    /// A cached version of the "goto" computation on LR(0) kernels 
-    let gotoKernel = 
-        Memoize (fun (GotoItemIdx(kernelIdx,sym)) -> 
-            let gset = ComputeGotosOfKernel (kernelTab.Kernel kernelIdx) sym
-            if gset.IsEmpty then None else Some (kernelTab.Index gset))
-
-    /// Iterate (iset,sym) pairs such that (gotoKernel kernelIdx sym) is not empty
-    let IterateGotosOfKernel kernelIdx f =
-        for sym in RelevantSymbolsOfKernel (kernelTab.Kernel kernelIdx) do 
-            match gotoKernel (GotoItemIdx(kernelIdx,sym)) with 
-            | None -> ()
-            | Some k -> f sym k
-    
-
-    // This is used to compute the closure of an LALR(1) kernel 
-    //
-    // For each item [A --> X.BY, a] in I
-    //   For each production B -> g in G'
-    //     For each terminal b in FIRST(Ya)
-    //        such that [B --> .g, b] is not in I do
-    //            add [B --> .g, b] to I
-    
-    let ComputeClosure1 iset = 
-        let acc = new Closure1Table()
-        ProcessWorkList iset (fun addToWorkList (item0,pretokens:Set<TerminalIndex>) ->
-            pretokens |> Set.iter (fun pretoken -> 
-                if not (acc.Contains(item0,pretoken)) then
-                    acc.Add(item0,pretoken) |> ignore
-                    let rsyms = rsyms_of_item0 item0 
-                    if rsyms.Length > 0 then 
-                        match rsyms.[0] with 
-                        | (PNonTerminal ntB) -> 
-                             let firstSet = ComputeFirstSetOfTokenList (Array.toList rsyms.[1..],pretoken)
-                             for prodIdx in prodTab.Productions.[ntB] do
-                                 addToWorkList (prodIdx_to_item0 prodIdx,firstSet)
-                        | PTerminal _ -> ()))
-        acc
-
-    // Compute the "spontaneous" and "propagate" maps for each LR(0) kernelItem 
-    //
-    // Input: The kernal K of a set of LR(0) items I and a grammar symbol X
-    //
-    // Output: The lookaheads generated spontaneously by items in I for kernel items 
-    // in goto(I,X) and the items I from which lookaheads are propagated to kernel
-    // items in goto(I,X)
-    //
-    // Method
-    //   1. Construct LR(0) kernel items (done - above)
-    //   2. 
-    // TODO: this is very, very slow. 
-    //
-    // PLAN TO OPTIMIZE THIS;
-    //   - Clarify and comment what's going on here
-    //   - verify if we really have to do these enormouos closure computations
-    //   - assess if it's possible to use the symbol we're looking for to help trim the jset
-    
-    reportTime(); printf "computing lookahead relations..."; stdout.Flush();
-
-        
-    let spontaneous, propagate  =
-        let closure1OfItem0WithDummy = 
-            Memoize (fun item0 -> ComputeClosure1 [(item0,Set.ofList [dummyLookaheadIdx])])
-
-        let spontaneous = new SpontaneousTable()
-        let propagate = new PropagateTable()
-        let count = ref 0 
-
-        for kernelIdx in kernelTab.Indexes do
-            printf  "."; stdout.Flush();
-            //printf  "kernelIdx = %d\n" kernelIdx; stdout.Flush();
-            let kernel = kernelTab.Kernel(kernelIdx)
-            for item0 in kernel do  
-                let item0Idx = KernelItemIdx(kernelIdx,item0)
-                let jset = closure1OfItem0WithDummy item0
-                //printf  "#jset = %d\n" jset.Count; stdout.Flush();
-                for (KeyValue(closureItem0, lookaheadTokens)) in jset.IEnumerable do
-                    incr count
-                    match rsym_of_item0 closureItem0 with 
-                    | None -> ()
-                    | Some rsym ->
-                         match gotoKernel (GotoItemIdx(kernelIdx,rsym)) with 
-                         | None -> ()
-                         | Some gotoKernelIdx ->
-                              let gotoItem = advance_of_item0 closureItem0
-                              let gotoItemIdx = KernelItemIdx(gotoKernelIdx,gotoItem)
-                              for lookaheadToken in lookaheadTokens do
-                                  if lookaheadToken = dummyLookaheadIdx 
-                                  then propagate.Add(item0Idx, gotoItemIdx) |> ignore
-                                  else spontaneous.Add(gotoItemIdx, lookaheadToken) |> ignore
-
-
-        //printfn "#kernelIdxs = %d, count = %d" kernelTab.Indexes.Length !count
-        spontaneous,
-        propagate
-   
-    //printfn "#spontaneous = %d, #propagate = %d" spontaneous.Count propagate.Count; stdout.Flush();
-   
-    //exit 0;
-    // Repeatedly use the "spontaneous" and "propagate" maps to build the full set 
-    // of lookaheads for each LR(0) kernelItem.   
-    reportTime(); printf  "building lookahead table..."; stdout.Flush();
-    let lookaheadTable = 
-
-        // Seed the table with the startKernelItems and the spontaneous info
-        let initialWork =
-            [ for idx in startKernelItemIdxs do
-                  yield (idx,endOfInputTerminalIdx)
-              for (KeyValue(kernelItemIdx,lookaheads)) in spontaneous.IEnumerable do
-                  for lookahead in lookaheads do
-                      yield (kernelItemIdx,lookahead) ]
-
-        let acc = new LookaheadTable()
-        // Compute the closure
-        ProcessWorkList 
-            initialWork
-            (fun queueWork (kernelItemIdx,lookahead) ->
-                acc.Add(kernelItemIdx,lookahead)
-                for gotoKernelIdx in propagate.[kernelItemIdx] do
-                    if not (acc.Contains(gotoKernelIdx,lookahead)) then 
-                        queueWork(gotoKernelIdx,lookahead))
-        acc
-
-    //printf  "built lookahead table, #lookaheads = %d\n" lookaheadTable.Count; stdout.Flush();
-
-    reportTime(); printf "building action table..."; stdout.Flush();
-    let shiftReduceConflicts = ref 0
-    let reduceReduceConflicts = ref 0
-    let actionTable, immediateActionTable = 
-
-        // Now build the action tables. First a utility to merge the given action  
-        // into the table, taking into account precedences etc. and reporting errors. 
-        let addResolvingPrecedence (arr: _[]) kernelIdx termIdx (precNew, actionNew) = 
-            // printf "DEBUG: state %d: adding action for %s, precNew = %a, actionNew = %a\n" kernelIdx (termTab.OfIndex termIdx) outputPrec precNew OutputAction actionNew; 
-            // We add in order of precedence - however the precedences may be the same, and we give warnings when rpecedence resolution is based on implicit file orderings 
-
-            let (precSoFar, actionSoFar) as itemSoFar = arr.[termIdx]
-
-            // printf "DEBUG: state %d: adding action for %s, precNew = %a, precSoFar = %a, actionSoFar = %a\n" kernelIdx (termTab.OfIndex termIdx) outputPrec precNew outputPrec precSoFar OutputAction actionSoFar; 
-            // if compare_prec precSoFar precNew = -1 then failwith "addResolvingPrecedence"; 
-
-            let itemNew = (precNew, actionNew) 
-            let winner = 
-                match itemSoFar,itemNew with 
-                | (_,Shift _),(_, Shift _) -> 
-                   if actionSoFar <> actionNew then 
-                      printf "internal error in fsyacc: shift/shift conflict";
-                   itemSoFar
-
-                | (((precShift,Shift _) as shiftItem), 
-                   ((precReduce,Reduce _) as reduceItem))
-                | (((precReduce,Reduce _) as reduceItem), 
-                   ((precShift,Shift _) as shiftItem)) -> 
-                    match precReduce, precShift with 
-                    | (ExplicitPrec (_,p1), ExplicitPrec(assocNew,p2)) -> 
-                      if p1 < p2 then shiftItem
-                      elif p1 > p2 then reduceItem
-                      else
-                        match precShift with 
-                        | ExplicitPrec(LeftAssoc,_) ->  reduceItem
-                        | ExplicitPrec(RightAssoc,_) -> shiftItem
-                        | _ ->
-                           printf "state %d: shift/reduce error on %s\n" kernelIdx (termTab.OfIndex termIdx); 
-                           incr shiftReduceConflicts;
-                           shiftItem
-                    | _ ->
-                       printf "state %d: shift/reduce error on %s\n" kernelIdx (termTab.OfIndex termIdx); 
-                       incr shiftReduceConflicts;
-                       shiftItem
-                | ((_,Reduce prodIdx1),(_, Reduce prodIdx2)) -> 
-                   printf "state %d: reduce/reduce error on %s\n" kernelIdx (termTab.OfIndex termIdx); 
-                   incr reduceReduceConflicts;
-                   if prodIdx1 < prodIdx2 then itemSoFar else itemNew
-                | _ -> itemNew 
-            arr.[termIdx] <- winner
-
-          
-        // This build the action table for one state. 
-        let ComputeActions kernelIdx = 
-            let kernel = kernelTab.Kernel kernelIdx
-            let arr = Array.create terminals.Length (NoPrecedence,Error)
-
-            //printf  "building lookahead table LR(1) items for kernelIdx %d\n" kernelIdx; stdout.Flush();
-
-            // Compute the LR(1) items based on lookaheads
-            let items = 
-                 [ for item0 in kernel do
-                     let kernelItemIdx = KernelItemIdx(kernelIdx,item0)
-                     let lookaheads = lookaheadTable.GetLookaheads(kernelItemIdx)
-                     yield (item0,lookaheads) ]
-                 |> ComputeClosure1
-
-            for (KeyValue(item0,lookaheads)) in items.IEnumerable do
-
-                let nonTermA = ntIdx_of_item0 item0
-                match rsym_of_item0 item0 with 
-                | Some (PTerminal termIdx) -> 
-                    let action =
-                      match gotoKernel (GotoItemIdx(kernelIdx,PTerminal termIdx)) with 
-                      | None -> failwith "action on terminal should have found a non-empty goto state"
-                      | Some gkernelItemIdx -> Shift gkernelItemIdx
-                    let prec = termTab.PrecInfoOfIndex termIdx
-                    addResolvingPrecedence arr kernelIdx termIdx (prec, action) 
-                | None ->
-                    for lookahead in lookaheads do
-                        if not (IsStartItem(item0)) then
-                            let prodIdx = prodIdx_of_item0 item0
-                            let prec = prec_of_item0 item0
-                            let action = (prec, Reduce prodIdx)
-                            addResolvingPrecedence arr kernelIdx lookahead action 
-                        elif lookahead = endOfInputTerminalIdx then
-                            let prec = prec_of_item0 item0
-                            let action = (prec,Accept)
-                            addResolvingPrecedence arr kernelIdx lookahead action 
-                        else ()
-                | _ -> ()
-
-            // If there is a single item A -> B C . and no Shift or Accept actions (i.e. only Error or Reduce, so the choice of terminal 
-            // cannot affect what we do) then we emit an immediate reduce action for the rule corresponding to that item 
-            // Also do the same for Accept rules. 
-            let closure = (ComputeClosure0 kernel)
-
-            let immediateAction =
-                match Set.toList closure with
-                | [item0] ->
-                    match (rsym_of_item0 item0) with 
-                    | None when (let reduceOrErrorAction = function Error | Reduce _ -> true | Shift _ | Accept -> false
-                                 termTab.Indexes |> List.forall(fun terminalIdx -> reduceOrErrorAction (snd(arr.[terminalIdx]))))
-                        -> Some (Reduce (prodIdx_of_item0 item0))
-
-                    | None when (let acceptOrErrorAction = function Error | Accept -> true | Shift _ | Reduce _ -> false
-                                 List.forall (fun terminalIdx -> acceptOrErrorAction (snd(arr.[terminalIdx]))) termTab.Indexes)
-                        -> Some Accept
-
-                    | _ -> None
-                | _ -> None
-
-            // A -> B C . rules give rise to reductions in favour of errors 
-            for item0 in ComputeClosure0 kernel do
-                let prec = prec_of_item0 item0
-                match rsym_of_item0 item0 with 
-                | None ->
-                    for terminalIdx in termTab.Indexes do 
-                        if snd(arr.[terminalIdx]) = Error then 
-                            let prodIdx = prodIdx_of_item0 item0
-                            let action = (prec, (if IsStartItem(item0) then Accept else Reduce prodIdx))
-                            addResolvingPrecedence arr kernelIdx terminalIdx action
-                | _  -> ()
-
-            arr,immediateAction
-
-        let actionInfo = List.map ComputeActions kernelTab.Indexes
-        Array.ofList (List.map fst actionInfo),
-        Array.ofList (List.map snd actionInfo)
-
-    // The goto table is much simpler - it is based on LR(0) kernels alone. 
-
-    reportTime(); printf  "building goto table..."; stdout.Flush();
-    let gotoTable = 
-         let gotos kernelIdx = Array.ofList (List.map (fun nt -> gotoKernel (GotoItemIdx(kernelIdx,PNonTerminal nt))) ntTab.Indexes)
-         Array.ofList (List.map gotos kernelTab.Indexes)
-
-    reportTime(); printfn  "returning tables."; stdout.Flush();
-    if !shiftReduceConflicts > 0 then printfn  "%d shift/reduce conflicts" !shiftReduceConflicts; stdout.Flush();
-    if !reduceReduceConflicts > 0 then printfn  "%d reduce/reduce conflicts" !reduceReduceConflicts; stdout.Flush();
-
-    /// The final results
-    let states = kernels |> Array.ofList 
-    let prods = Array.ofList (List.map (fun (Production(nt,prec,syms,code)) -> (nt, ntTab.ToIndex nt, syms,code)) prods)
-
-    logf (fun logStream -> 
-        printf  "writing tables to log\n"; stdout.Flush();
-        OutputLalrTables logStream     (prods, states, startKernelIdxs, actionTable, immediateActionTable, gotoTable, (termTab.ToIndex endOfInputTerminal), errorTerminalIdx));
-
-    let states = states |> Array.map (Set.toList >> List.map prodIdx_of_item0)
-    (prods, states, startKernelIdxs, 
-     actionTable, immediateActionTable, gotoTable, 
-     (termTab.ToIndex endOfInputTerminal), 
-     errorTerminalIdx, nonTerminals)
-
-  
-(* Some examples for testing *)  
-
-(*
-
-let example1 = 
-  let e = "E" 
-  let t = "Terminal"
-  let plus = "+"
-  let mul = "*"
-  let f = "F"
-  let lparen = "("
-  let rparen = ")"
-  let id = "id"
-  
-  let terminals = [plus; mul; lparen; rparen; id]
-  let nonTerminals = [e; t; f]
-  
-  let p2 = e, (NonAssoc, ExplicitPrec 1), [NonTerminal e; Terminal plus; NonTerminal t], None
-  let p3 = e, (NonAssoc, ExplicitPrec 2), [NonTerminal t], None in  
-  let p4 = t, (NonAssoc, ExplicitPrec 3), [NonTerminal t; Terminal mul; NonTerminal f], None
-  let p5 = t, (NonAssoc, ExplicitPrec 4), [NonTerminal f], None
-  let p6 = f, (NonAssoc, ExplicitPrec  5), [Terminal lparen; NonTerminal e; Terminal rparen], None
-  let p7 = f, (NonAssoc, ExplicitPrec 6), [Terminal id], None
-
-  let prods = [p2;p3;p4;p5;p6;p7]
-  Spec(terminals,nonTerminals,prods, [e])
-
-let example2 = 
-  let prods = [ "S", (NonAssoc, ExplicitPrec 1), [NonTerminal "C";NonTerminal "C"], None; 
-                "C", (NonAssoc, ExplicitPrec 2), [Terminal "c";NonTerminal "C"], None ;
-                "C", (NonAssoc, ExplicitPrec 3), [Terminal "d"] , None  ]in
-  Spec(["c";"d"],["S";"C"],prods, ["S"])
-
-let example3 = 
-  let terminals = ["+"; "*"; "("; ")"; "id"]
-  let nonTerminals = ["E"; "Terminal"; "E'"; "F"; "Terminal'"]
-  let prods = [ "E", (NonAssoc, ExplicitPrec 1), [ NonTerminal "Terminal"; NonTerminal "E'" ], None;
-                "E'", (NonAssoc, ExplicitPrec 2), [ Terminal "+"; NonTerminal "Terminal"; NonTerminal "E'"], None;
-                "E'", (NonAssoc, ExplicitPrec 3), [ ], None;
-                "Terminal", (NonAssoc, ExplicitPrec 4), [ NonTerminal "F"; NonTerminal "Terminal'" ], None;
-                "Terminal'", (NonAssoc, ExplicitPrec 5), [ Terminal "*"; NonTerminal "F"; NonTerminal "Terminal'"], None;
-                "Terminal'", (NonAssoc, ExplicitPrec 6), [ ], None;
-                "F", (NonAssoc, ExplicitPrec 7), [ Terminal "("; NonTerminal "E"; Terminal ")"], None;
-                "F", (NonAssoc, ExplicitPrec 8), [ Terminal "id"], None ]
-  Spec(terminals,nonTerminals,prods, ["E"])
-
-let example4 = 
-  let terminals = ["+"; "*"; "("; ")"; "id"]
-  let nonTerminals = ["E"]
-  let prods = [ "E", (NonAssoc, ExplicitPrec 1), [ NonTerminal "E"; Terminal "+"; NonTerminal "E" ], None;
-                "E", (NonAssoc, ExplicitPrec 2), [ NonTerminal "E"; Terminal "*"; NonTerminal "E" ], None;
-                "E", (NonAssoc, ExplicitPrec 3), [ Terminal "("; NonTerminal "E"; Terminal ")"], None;
-                "E", (NonAssoc, ExplicitPrec 8), [ Terminal "id"],  None ]
-  Spec(terminals,nonTerminals,prods, ["E"])
-
-let example5 = 
-  let terminals = ["+"; "*"; "("; ")"; "id"]
-  let nonTerminals = ["E"]
-  let prods = [ "E", (NonAssoc, ExplicitPrec 1), [ NonTerminal "E"; Terminal "+"; NonTerminal "E" ], None;
-                "E", (NonAssoc, ExplicitPrec 2), [ NonTerminal "E"; Terminal "*"; NonTerminal "E" ], None;
-                "E", (NonAssoc, ExplicitPrec 3), [ Terminal "("; NonTerminal "E"; Terminal ")"], None;
-                "E", (NonAssoc, ExplicitPrec 8), [ Terminal "id"], None ]
-  Spec(terminals,nonTerminals,prods, ["E"])
-
-let example6 = 
-  let terminals = ["+"; "*"; "("; ")"; "id"; "-"]
-  let nonTerminals = ["E"]
-  let prods = [ "E", (RightAssoc, ExplicitPrec 1), [ NonTerminal "E"; Terminal "-"; NonTerminal "E" ], None;
-                "E", (LeftAssoc, ExplicitPrec 1), [ NonTerminal "E"; Terminal "+"; NonTerminal "E" ], None;
-                "E", (LeftAssoc, ExplicitPrec 2), [ NonTerminal "E"; Terminal "*"; NonTerminal "E" ], None;
-                "E", (NonAssoc, ExplicitPrec 3), [ Terminal "("; NonTerminal "E"; Terminal ")"], None;
-                "E", (NonAssoc, ExplicitPrec 8), [ Terminal "id"], None ]
-  Spec(terminals,nonTerminals,prods, ["E"])
-
-
-let example7 = 
-  let prods = [ "S", (NonAssoc, ExplicitPrec 1), [NonTerminal "L";Terminal "="; NonTerminal "R"], None; 
-                "S", (NonAssoc, ExplicitPrec 2), [NonTerminal "R"], None ;
-                "L", (NonAssoc, ExplicitPrec 3), [Terminal "*"; NonTerminal "R"], None;
-                "L", (NonAssoc, ExplicitPrec 3), [Terminal "id"], None; 
-                "R", (NonAssoc, ExplicitPrec 3), [NonTerminal "L"], None; ]
-  Spec(["*";"=";"id"],["S";"L";"R"],prods, ["S"])
-
-
-
-let test ex = CompilerLalrParserSpec stdout ex
-
-(* let _ = test example2*)
-(* let _ = exit 1*)
-(* let _ = test example3 
-let _ = test example1  
-let _ = test example4
-let _ = test example5
-let _ = test example6 *)
-*)
+// (c) Microsoft Corporation 2005-2007.
+
+module internal FSharp.PowerPack.FsYacc.AST
+
+#nowarn "62" // This construct is for ML compatibility.
+
+
+open System
+open System.Collections.Generic
+open Printf
+open Microsoft.FSharp.Collections
+open Internal.Utilities
+open Internal.Utilities.Text.Lexing
+
+/// An active pattern that should be in the F# standard library
+let (|KeyValue|) (kvp:KeyValuePair<_,_>) = kvp.Key,kvp.Value
+
+
+type Identifier = string
+type Code = string * Position
+
+type ParserSpec= 
+    { Header         : Code;
+      Tokens         : (Identifier * string option) list;
+      Types          : (Identifier * string) list;
+      Associativities: (Identifier * Associativity) list list;
+      StartSymbols   : Identifier list;
+      Rules          : (Identifier * Rule list) list }
+      
+and Rule = Rule of Identifier list * Identifier option * Code option
+and Associativity = LeftAssoc | RightAssoc | NonAssoc
+
+type Terminal = string
+type NonTerminal = string
+type Symbol = Terminal of Terminal | NonTerminal of NonTerminal
+type Symbols = Symbol list
+
+
+//---------------------------------------------------------------------
+// Output Raw Parser Spec AST
+
+let StringOfSym sym = match sym with Terminal s -> "'" ^ s ^ "'" | NonTerminal s -> s
+
+let OutputSym os sym = fprintf os "%s" (StringOfSym sym)
+
+let OutputSyms os syms =
+    fprintf os "%s" (String.Join(" ",Array.map StringOfSym syms))
+
+let OutputTerminalSet os (tset:string seq)  =
+    fprintf os "%s" (String.Join(";", tset |> Seq.toArray))
+
+let OutputAssoc os p = 
+    match p with 
+    | LeftAssoc -> fprintf os "left"
+    | RightAssoc -> fprintf os "right"
+    | NonAssoc -> fprintf os "nonassoc"
+
+
+//---------------------------------------------------------------------
+// PreProcess Raw Parser Spec AST
+
+type PrecedenceInfo = 
+    | ExplicitPrec of Associativity * int 
+    | NoPrecedence
+      
+type Production = Production of NonTerminal * PrecedenceInfo * Symbols * Code option
+
+type ProcessedParserSpec = 
+    { Terminals: (Terminal * PrecedenceInfo) list;
+      NonTerminals: NonTerminal list;
+      Productions: Production list;
+      StartSymbols: NonTerminal list }
+
+
+let ProcessParserSpecAst (spec: ParserSpec) = 
+    let explicitPrecInfo = 
+        spec.Associativities 
+        |> List.mapi (fun n precSpecs -> precSpecs |> List.map (fun (precSym, assoc) -> precSym,ExplicitPrec (assoc, 10000 - n)))
+        |> List.concat
+    
+    for (key,_) in explicitPrecInfo |> Seq.countBy fst |> Seq.filter (fun (_,n) -> n > 1)  do
+        failwithf "%s is given two associativities" key
+    
+    let explicitPrecInfo = 
+        explicitPrecInfo |> Map.ofList
+
+    let implicitSymPrecInfo = NoPrecedence
+    let terminals = List.map fst spec.Tokens @ ["error"]in 
+    let terminalSet = Set.ofList terminals
+    let IsTerminal z = terminalSet.Contains(z)
+    let prec_of_terminal sym implicitPrecInfo = 
+       if explicitPrecInfo.ContainsKey(sym) then explicitPrecInfo.[sym]
+       else match implicitPrecInfo with Some x -> x | None -> implicitSymPrecInfo
+       
+    let mkSym s = if IsTerminal s then Terminal s else NonTerminal s
+    let prods =  
+        spec.Rules |> List.mapi (fun i (nonterm,rules) -> 
+            rules |> List.mapi (fun j (Rule(syms,precsym,code)) -> 
+                let precInfo = 
+                    let precsym = List.foldBack (fun x acc -> match acc with Some _ -> acc | None -> match x with z when IsTerminal z -> Some z | _ -> acc) syms precsym
+                    let implicitPrecInfo = NoPrecedence
+                    match precsym with 
+                    | None -> implicitPrecInfo 
+                    | Some sym -> if explicitPrecInfo.ContainsKey(sym) then explicitPrecInfo.[sym] else implicitPrecInfo
+                Production(nonterm, precInfo, List.map mkSym syms, code)))
+         |> List.concat
+    let nonTerminals = List.map fst spec.Rules
+    let nonTerminalSet = Set.ofList nonTerminals
+    let checkNonTerminal nt =  
+        if nt <> "error" && not (nonTerminalSet.Contains(nt)) then 
+            failwith (sprintf "NonTerminal '%s' has no productions" nt)
+
+    for (Production(nt,_,syms,_)) in prods do
+        for sym in syms do 
+           match sym with 
+           | NonTerminal nt -> 
+               checkNonTerminal nt 
+           | Terminal t ->  
+               if not (IsTerminal t) then failwith (sprintf "token %s is not declared" t)
+           
+    if spec.StartSymbols= [] then (failwith "at least one %start declaration is required\n");
+
+    for (nt,_) in spec.Types do 
+        checkNonTerminal nt;
+
+    let terminals = terminals |> List.map (fun t -> (t,prec_of_terminal t None)) 
+
+    { Terminals=terminals;
+      NonTerminals=nonTerminals;
+      Productions=prods;
+      StartSymbols=spec.StartSymbols }
+
+
+//-------------------------------------------------
+// Process LALR(1) grammars to tables
+
+type ProductionIndex = int
+type ProdictionDotIndex = int
+
+/// Represent (ProductionIndex,ProdictionDotIndex) as one integer 
+type Item0 = uint32  
+
+let mkItem0 (prodIdx,dotIdx) : Item0 = (uint32 prodIdx <<< 16) ||| uint32 dotIdx
+let prodIdx_of_item0 (item0:Item0) = int32 (item0 >>> 16)
+let dotIdx_of_item0 (item0:Item0) = int32 (item0 &&& 0xFFFFu)
+
+/// Part of the output of CompilerLalrParserSpec
+type Action = 
+  | Shift of int
+  | Reduce of ProductionIndex
+  | Accept
+  | Error
+    
+let outputPrecInfo os p = 
+    match p with 
+    | ExplicitPrec (assoc,n) -> fprintf os "explicit %a %d" OutputAssoc assoc n
+    | NoPrecedence  -> fprintf os "noprec"
+
+
+/// LR(0) kernels
+type Kernel = Set<Item0>
+
+/// Indexes of LR(0) kernels in the KernelTable
+type KernelIdx = int
+
+/// Indexes in the TerminalTable and NonTerminalTable
+type TerminalIndex = int
+type NonTerminalIndex = int
+
+/// Representation of Symbols.
+/// Ideally would be declared as 
+///    type SymbolIndex = PTerminal of TerminalIndex | PNonTerminal of NonTerminalIndex
+/// but for performance reasons we embed as a simple integer (saves ~10%)
+///
+/// We use an active pattern to reverse the embedding.
+type SymbolIndex = int
+let PTerminal(i:TerminalIndex) : SymbolIndex = -i-1
+let PNonTerminal(i:NonTerminalIndex) : SymbolIndex = i
+let (|PTerminal|PNonTerminal|) x = if x < 0 then PTerminal (-(x+1)) else PNonTerminal x
+
+type SymbolIndexes = SymbolIndex list
+
+/// Indexes in the LookaheadTable, SpontaneousTable, PropagateTable
+/// Embed in a single integer, since these are faster
+/// keys for the dictionary hash tables
+///
+/// Logically:
+///
+///   type KernelItemIndex = KernelItemIdx of KernelIdx * Item0
+type KernelItemIndex = int64
+let KernelItemIdx (i1,i2) = ((int64 i1) <<< 32) ||| int64 i2
+
+
+/// Indexes into the memoizing table for the Goto computations
+/// Embed in a single integer, since these are faster
+/// keys for the dictionary hash tables
+///
+/// Logically:
+///
+///   type GotoItemIndex = GotoItemIdx of KernelIdx * SymbolIndex
+type GotoItemIndex = uint64
+let GotoItemIdx (i1:KernelIdx,i2:SymbolIndex) = (uint64 (uint32 i1) <<< 32) ||| uint64 (uint32 i2)
+let (|GotoItemIdx|) (i64:uint64) = int32 ((i64 >>> 32) &&& 0xFFFFFFFFUL), int32 (i64 &&& 0xFFFFFFFFUL)
+
+/// Create a work list and loop until it is exhausted, calling a worker function for
+/// each element. Pass a function to queue additional work on the work list 
+/// to the worker function
+let ProcessWorkList start f =
+    let work = ref (start : 'a list)
+    let queueWork = (fun x -> work := x :: !work)
+    let rec loop() = 
+        match !work with 
+        | [] -> ()
+        | x::t -> 
+            work := t; 
+            f queueWork x;
+            loop()
+    loop()
+
+/// A standard utility to compute a least fixed point of a set under a generative computation
+let LeastFixedPoint f set = 
+    let acc = ref set
+    ProcessWorkList (Set.toList set) (fun queueWork item ->
+          f(item) |> List.iter (fun i2 -> if not (Set.contains i2 !acc) then (acc := Set.add i2 !acc; queueWork i2)) )
+    !acc
+
+/// A general standard memoization utility. Be sure to apply to only one (function) argument to build the
+/// residue function!
+let Memoize f = 
+    let t = new Dictionary<_,_>(1000)
+    fun x -> 
+        let ok,v = t.TryGetValue(x) 
+        if ok then v else let res = f x in t.[x] <- res; res 
+
+/// A standard utility to create a dictionary from a list of pairs
+let CreateDictionary xs = 
+    let dict = new Dictionary<_,_>()
+    for x,y in xs do dict.Add(x,y)
+    dict
+
+/// Allocate indexes for each non-terminal
+type NonTerminalTable(nonTerminals:NonTerminal list) = 
+    let nonterminalsWithIdxs = List.mapi (fun (i:NonTerminalIndex) n -> (i,n)) nonTerminals
+    let nonterminalIdxs = List.map fst nonterminalsWithIdxs
+    let a = Array.ofList nonTerminals
+    let b = CreateDictionary [ for i,x in nonterminalsWithIdxs -> x,i ];
+    member table.OfIndex(i) = a.[i]
+    member table.ToIndex(i) = b.[i]
+    member table.Indexes = nonterminalIdxs
+
+/// Allocate indexes for each terminal
+type TerminalTable(terminals:(Terminal * PrecedenceInfo) list) = 
+    let terminalsWithIdxs = List.mapi (fun i (t,_) -> (i,t)) terminals
+    let terminalIdxs = List.map fst terminalsWithIdxs
+    let a = Array.ofList (List.map fst terminals)
+    let b = Array.ofList (List.map snd terminals)
+    let c = CreateDictionary [ for i,x in terminalsWithIdxs -> x,i ]
+
+    member table.OfIndex(i) = a.[i]
+    member table.PrecInfoOfIndex(i) = b.[i]
+    member table.ToIndex(i) = c.[i]
+    member table.Indexes = terminalIdxs
+
+/// Allocate indexes for each production
+type ProductionTable(ntTab:NonTerminalTable, termTab:TerminalTable, nonTerminals:string list, prods: Production list) =
+    let prodsWithIdxs = List.mapi (fun i n -> (i,n)) prods
+    let a =  
+        prodsWithIdxs
+        |> List.map(fun (_,Production(_,_,syms,_)) -> 
+              syms 
+              |> Array.ofList  
+              |> Array.map (function 
+                            | Terminal t -> PTerminal (termTab.ToIndex t) 
+                            | NonTerminal nt -> PNonTerminal (ntTab.ToIndex nt )) )
+        |> Array.ofList
+    let b = Array.ofList (List.map (fun (_,Production(nt,_,_,_)) -> ntTab.ToIndex nt) prodsWithIdxs)
+    let c = Array.ofList (List.map (fun (_,Production(_,prec,_,_)) -> prec) prodsWithIdxs)
+    let productions = 
+        nonTerminals
+        |> List.map(fun nt -> (ntTab.ToIndex nt, List.choose (fun (i,Production(nt2,prec,syms,_)) -> if nt2=nt then Some i else None) prodsWithIdxs))
+        |> CreateDictionary
+
+    member prodTab.Symbols(i) = a.[i]
+    member prodTab.NonTerminal(i) = b.[i]
+    member prodTab.Precedence(i) = c.[i]
+    member prodTab.Symbol i n = 
+        let syms = prodTab.Symbols i
+        if n >= syms.Length then None else Some (syms.[n])
+    member prodTab.Productions = productions
+
+/// A mutable table maping kernels to sets of lookahead tokens
+type LookaheadTable() = 
+    let t = new Dictionary<KernelItemIndex,Set<TerminalIndex>>()
+    member table.Add(x,y) = 
+        let prev = if t.ContainsKey(x) then t.[x] else Set.empty 
+        t.[x] <- prev.Add(y)
+    member table.Contains(x,y) = t.ContainsKey(x) && t.[x].Contains(y)
+    member table.GetLookaheads(idx:KernelItemIndex) = 
+        let ok,v = t.TryGetValue(idx)  
+        if ok then v else Set.empty
+    member table.Count = t |> Seq.fold(fun acc (KeyValue(_,v)) -> v.Count+acc) 0
+
+/// A mutable table giving an index to each LR(0) kernel. Kernels are referred to only by index.
+type KernelTable(kernels) =
+    // Give an index to each LR(0) kernel, and from now on refer to them only by index 
+    // Also develop "kernelItemIdx" to refer to individual items within a kernel 
+    let kernelsAndIdxs = List.mapi (fun i x -> (i,x)) kernels
+    let kernelIdxs = List.map fst kernelsAndIdxs
+    let toIdxMap = Map.ofList [ for i,x in kernelsAndIdxs -> x,i ]
+    let ofIdxMap = Array.ofList kernels
+    member t.Indexes = kernelIdxs
+    member t.Index(kernel) = toIdxMap.[kernel]
+    member t.Kernel(i) = ofIdxMap.[i]
+
+/// Hold the results of cpmuting the LALR(1) closure of an LR(0) kernel
+type Closure1Table() = 
+    let t = new Dictionary<Item0,HashSet<TerminalIndex>>()
+    member table.Add(a,b) = 
+        if not (t.ContainsKey(a)) then t.[a] <- new HashSet<_>(HashIdentity.Structural)
+        t.[a].Add(b)
+    member table.Count  = t.Count
+    member table.IEnumerable = (t :> seq<_>)
+    member table.Contains(a,b) = t.ContainsKey(a) && t.[a].Contains(b)
+
+/// A mutable table giving a lookahead set Set<Terminal> for each kernel. The terminals represent the
+/// "spontaneous" items for the kernel. TODO: document this more w.r.t. the Dragon book.
+type SpontaneousTable() = 
+    let t = new Dictionary<KernelItemIndex,HashSet<TerminalIndex>>()
+    member table.Add(a,b) = 
+        if not (t.ContainsKey(a)) then t.[a] <- new HashSet<_>(HashIdentity.Structural)
+        t.[a].Add(b)
+    member table.Count  = t.Count
+    member table.IEnumerable = (t :> seq<_>)
+
+/// A mutable table giving a Set<KernelItemIndex> for each kernel. The kernels represent the
+/// "propagate" items for the kernel. TODO: document this more w.r.t. the Dragon book.
+type PropagateTable() = 
+    let t = new Dictionary<KernelItemIndex,HashSet<KernelItemIndex>>()
+    member table.Add(a,b) = 
+        if not (t.ContainsKey(a)) then t.[a] <- new HashSet<KernelItemIndex>(HashIdentity.Structural)
+        t.[a].Add(b)
+    member table.Item 
+      with get(a) = 
+        let ok,v = t.TryGetValue(a) 
+        if ok then v :> seq<_> else Seq.empty
+    member table.Count  = t.Count
+
+
+/// Compile a pre-processed LALR parser spec to tables following the Dragon book algorithm
+let CompilerLalrParserSpec logf (spec : ProcessedParserSpec) =
+    let stopWatch = new System.Diagnostics.Stopwatch()
+    let reportTime() = printfn "time: %A" stopWatch.Elapsed; stopWatch.Reset(); stopWatch.Start()
+    stopWatch.Start()
+
+    // Augment the grammar 
+    let fakeStartNonTerminals = spec.StartSymbols |> List.map(fun nt -> "_start"^nt) 
+    let nonTerminals = fakeStartNonTerminals@spec.NonTerminals
+    let endOfInputTerminal = "$$"
+    let dummyLookahead = "#"
+    let dummyPrec = NoPrecedence
+    let terminals = spec.Terminals @ [(dummyLookahead,dummyPrec); (endOfInputTerminal,dummyPrec)]
+    let prods = List.map2 (fun a b -> Production(a, dummyPrec,[NonTerminal b],None)) fakeStartNonTerminals spec.StartSymbols @ spec.Productions
+    let startNonTerminalIdx_to_prodIdx (i:int) = i
+
+    // Build indexed tables 
+    let ntTab = NonTerminalTable(nonTerminals)
+    let termTab = TerminalTable(terminals)
+    let prodTab = ProductionTable(ntTab,termTab,nonTerminals,prods)
+    let dummyLookaheadIdx = termTab.ToIndex dummyLookahead
+    let endOfInputTerminalIdx = termTab.ToIndex endOfInputTerminal
+
+
+    // printf "terminalPrecInfo(ELSE) = %a\n" outputPrecInfo (termTab.PrecInfoOfIndex (termTab.ToIndex "ELSE"));
+
+    let errorTerminalIdx = termTab.ToIndex "error"
+
+    // Compute the FIRST function
+    printf  "computing first function..."; stdout.Flush();
+
+    let computedFirstTable = 
+        let seed = 
+            Map.ofList
+             [ for term in termTab.Indexes do yield (PTerminal(term),Set.singleton (Some term))
+               for nonTerm in ntTab.Indexes do 
+                  yield 
+                    (PNonTerminal nonTerm, 
+                     List.foldBack 
+                       (fun prodIdx acc -> match prodTab.Symbol prodIdx 0 with None -> Set.add None acc | Some _ -> acc) 
+                       prodTab.Productions.[nonTerm] 
+                       Set.empty) ]
+                 
+        let add changed ss (x,y) = 
+            let s = Map.find x ss
+            if Set.contains y s then ss 
+            else (changed := true; Map.add x (Set.add y s) ss)
+
+        let oneRound (ss:Map<_,_>) = 
+            let changed = ref false
+            let frontier = 
+                let res = ref []
+                for nonTermX in ntTab.Indexes do 
+                    for prodIdx in prodTab.Productions.[nonTermX] do
+                        let rhs = Array.toList (prodTab.Symbols prodIdx)
+                        let rec place l =
+                            match l with
+                            | (yi::t) -> 
+                                res := 
+                                   List.choose 
+                                     (function None -> None | Some a -> Some (PNonTerminal nonTermX,Some a)) 
+                                     (Set.toList ss.[yi]) 
+                                   @ !res;
+                                if ss.[yi].Contains(None) then place t;
+                            | [] -> 
+                                res := (PNonTerminal nonTermX,None) :: !res
+                        place rhs
+                !res
+            let ss' = List.fold (add changed) ss frontier
+            !changed, ss'
+
+        let rec loop ss = 
+            let changed, ss' = oneRound ss
+            if changed then loop ss' else ss'
+        loop seed 
+            
+      
+    /// Compute the first set of the given sequence of non-terminals. If any of the non-terminals
+    /// have an empty token in the first set then we have to iterate through those. 
+    let ComputeFirstSetOfTokenList =
+        Memoize (fun (str,term) -> 
+            let acc = new System.Collections.Generic.List<_>()
+            let rec add l = 
+                match l with 
+                | [] -> acc.Add(term)
+                | sym::moreSyms -> 
+                    let firstSetOfSym = computedFirstTable.[sym]
+                    firstSetOfSym |> Set.iter (function None -> () | Some v -> acc.Add(v)) 
+                    if firstSetOfSym.Contains(None) then add moreSyms 
+            add str;
+            Set.ofSeq acc)
+    
+    // (int,int) representation of LR(0) items 
+    let prodIdx_to_item0 idx = mkItem0(idx,0) 
+    let prec_of_item0 item0 = prodTab.Precedence (prodIdx_of_item0 item0)
+    let ntIdx_of_item0 item0 = prodTab.NonTerminal (prodIdx_of_item0 item0)
+
+    let lsyms_of_item0 item0 = 
+        let prodIdx = prodIdx_of_item0 item0
+        let dotIdx = dotIdx_of_item0 item0
+        let syms = prodTab.Symbols prodIdx
+        syms.[..dotIdx-1]
+
+    let rsyms_of_item0 item0 = 
+        let prodIdx = prodIdx_of_item0 item0
+        let dotIdx = dotIdx_of_item0 item0
+        let syms = prodTab.Symbols prodIdx
+        syms.[dotIdx..]
+
+    let rsym_of_item0 item0 = 
+        let prodIdx = prodIdx_of_item0 item0
+        let dotIdx = dotIdx_of_item0 item0
+        prodTab.Symbol prodIdx dotIdx
+
+    let advance_of_item0 item0 = 
+        let prodIdx = prodIdx_of_item0 item0
+        let dotIdx = dotIdx_of_item0 item0
+        mkItem0(prodIdx,dotIdx+1)
+    let fakeStartNonTerminalsSet = Set.ofList (fakeStartNonTerminals |> List.map ntTab.ToIndex)
+
+    let IsStartItem item0 = fakeStartNonTerminalsSet.Contains(ntIdx_of_item0 item0)
+    let IsKernelItem item0 = (IsStartItem item0 || dotIdx_of_item0 item0 <> 0)
+
+    let StringOfSym sym = match sym with PTerminal s -> "'" ^ termTab.OfIndex s ^ "'" | PNonTerminal s -> ntTab.OfIndex s
+
+    let OutputSym os sym = fprintf os "%s" (StringOfSym sym)
+
+    let OutputSyms os syms =
+        fprintf os "%s" (String.Join(" ",Array.map StringOfSym syms))
+
+    // Print items and other stuff 
+    let OutputItem0 os item0 =
+        fprintf os "    %s -> %a . %a" (ntTab.OfIndex (ntIdx_of_item0 item0)) (* outputPrecInfo precInfo *) OutputSyms (lsyms_of_item0 item0) OutputSyms (rsyms_of_item0 item0) 
+        
+    let OutputItem0Set os s = 
+        Set.iter (fun item -> fprintf os "%a\n" OutputItem0 item) s
+
+    let OutputFirstSet os m = 
+        Set.iter (function None ->  fprintf os "<empty>" | Some x -> fprintf os "  term %s\n" x) m
+
+    let OutputFirstMap os m = 
+        Map.iter (fun x y -> fprintf os "first '%a' = \n%a\n" OutputSym x OutputFirstSet y) m
+
+    let OutputAction os m = 
+        match m with 
+        | Shift n -> fprintf os "  shift %d" n 
+        | Reduce prodIdx ->  fprintf os "  reduce %s --> %a" (ntTab.OfIndex (prodTab.NonTerminal prodIdx)) OutputSyms (prodTab.Symbols prodIdx)
+        | Error ->  fprintf os "  error"
+        | Accept -> fprintf os "  accept" 
+    
+    let OutputActions os m = 
+        Array.iteri (fun i (prec,action) -> let term = termTab.OfIndex i in fprintf os "    action '%s' (%a): %a\n" term outputPrecInfo prec OutputAction action) m
+
+    let OutputActionTable os m = 
+        Array.iteri (fun i n -> fprintf os "state %d:\n%a\n" i OutputActions n) m
+
+    let OutputImmediateActions os m = 
+        match m with 
+        | None -> fprintf os "<none>"
+        | Some a -> OutputAction os a
+    
+    let OutputGotos os m = 
+        Array.iteri (fun ntIdx s -> let nonterm = ntTab.OfIndex ntIdx in match s with Some st -> fprintf os "    goto %s: %d\n" nonterm st | None -> ()) m
+    
+    let OutputCombined os m = 
+        Array.iteri (fun i (a,b,c,d) -> fprintf os "state %d:\n  items:\n%a\n  actions:\n%a\n  immediate action: %a\n gotos:\n%a\n" i OutputItem0Set a OutputActions b OutputImmediateActions c OutputGotos d) m
+    
+    let OutputLalrTables os (prods,states, startStates,actionTable,immediateActionTable,gotoTable,endOfInputTerminalIdx,errorTerminalIdx) = 
+        let combined = Array.ofList (List.map2 (fun x (y,(z,w)) -> x,y,z,w) (Array.toList states) (List.zip (Array.toList actionTable) (List.zip (Array.toList immediateActionTable) (Array.toList gotoTable))))
+        fprintfn os "------------------------";
+        fprintfn os "states = ";
+        fprintfn os "%a" OutputCombined combined;
+        fprintfn os "startStates = %s" (String.Join(";",Array.ofList (List.map string startStates)));
+        fprintfn os "------------------------"
+
+
+    // Closure of LR(0) nonTerminals, items etc 
+    let ComputeClosure0NonTerminal = 
+        Memoize (fun nt -> 
+            let seed = (List.foldBack (prodIdx_to_item0 >> Set.add) prodTab.Productions.[nt] Set.empty)
+            LeastFixedPoint 
+                (fun item0 -> 
+                   match rsym_of_item0 item0 with
+                   | None -> []
+                   | Some(PNonTerminal ntB) ->  List.map prodIdx_to_item0 prodTab.Productions.[ntB]
+                   | Some(PTerminal _) -> [])
+                seed)
+
+    // Close a symbol under epsilon moves
+    let ComputeClosure0Symbol rsym acc = 
+        match rsym with
+        | Some (PNonTerminal nt) -> Set.union (ComputeClosure0NonTerminal nt) acc
+        | _ -> acc
+
+    // Close a set under epsilon moves
+    let ComputeClosure0 iset = 
+        Set.fold (fun acc x -> ComputeClosure0Symbol (rsym_of_item0 x) acc) iset iset 
+
+    // Right symbols after closing under epsilon moves
+    let RelevantSymbolsOfKernel kernel =
+        let kernelClosure0 = ComputeClosure0 kernel
+        Set.fold (fun acc x -> Option.fold (fun acc x -> Set.add x acc) acc (rsym_of_item0 x)) Set.empty kernelClosure0 
+
+    // Goto set of a kernel of LR(0) nonTerminals, items etc 
+    // Input is kernel, output is kernel
+    let ComputeGotosOfKernel iset sym = 
+        let isetClosure = ComputeClosure0 iset
+        let acc = new System.Collections.Generic.List<_>(10)
+        isetClosure |> Set.iter (fun item0 -> 
+              match rsym_of_item0 item0 with 
+              | Some sym2 when sym = sym2 -> acc.Add(advance_of_item0 item0) 
+              | _ -> ()) 
+        Set.ofSeq acc
+    
+    // Build the full set of LR(0) kernels 
+    reportTime(); printf "building kernels..."; stdout.Flush();
+    let startItems = List.mapi (fun i _ -> prodIdx_to_item0 (startNonTerminalIdx_to_prodIdx i)) fakeStartNonTerminals
+    let startKernels = List.map Set.singleton startItems
+    let kernels = 
+
+        /// We use a set-of-sets here. F# sets support structural comparison but at the time of writing
+        /// did not structural hashing. 
+        let acc = ref Set.empty
+        ProcessWorkList startKernels (fun addToWorkList kernel -> 
+            if not ((!acc).Contains(kernel)) then
+                acc := (!acc).Add(kernel);
+                for csym in RelevantSymbolsOfKernel kernel do 
+                    let gotoKernel = ComputeGotosOfKernel kernel csym 
+                    assert (gotoKernel.Count > 0)
+                    addToWorkList gotoKernel )
+                    
+        !acc |> Seq.toList |> List.map (Set.filter IsKernelItem)
+    
+    reportTime(); printf "building kernel table..."; stdout.Flush();
+    // Give an index to each LR(0) kernel, and from now on refer to them only by index 
+    let kernelTab = new KernelTable(kernels)
+    let startKernelIdxs = List.map kernelTab.Index startKernels
+    let startKernelItemIdxs = List.map2 (fun a b -> KernelItemIdx(a,b)) startKernelIdxs startItems
+
+    let outputKernelItemIdx os (kernelIdx,item0)  =
+        fprintf os "kernel %d, item %a" kernelIdx OutputItem0 item0
+
+    /// A cached version of the "goto" computation on LR(0) kernels 
+    let gotoKernel = 
+        Memoize (fun (GotoItemIdx(kernelIdx,sym)) -> 
+            let gset = ComputeGotosOfKernel (kernelTab.Kernel kernelIdx) sym
+            if gset.IsEmpty then None else Some (kernelTab.Index gset))
+
+    /// Iterate (iset,sym) pairs such that (gotoKernel kernelIdx sym) is not empty
+    let IterateGotosOfKernel kernelIdx f =
+        for sym in RelevantSymbolsOfKernel (kernelTab.Kernel kernelIdx) do 
+            match gotoKernel (GotoItemIdx(kernelIdx,sym)) with 
+            | None -> ()
+            | Some k -> f sym k
+    
+
+    // This is used to compute the closure of an LALR(1) kernel 
+    //
+    // For each item [A --> X.BY, a] in I
+    //   For each production B -> g in G'
+    //     For each terminal b in FIRST(Ya)
+    //        such that [B --> .g, b] is not in I do
+    //            add [B --> .g, b] to I
+    
+    let ComputeClosure1 iset = 
+        let acc = new Closure1Table()
+        ProcessWorkList iset (fun addToWorkList (item0,pretokens:Set<TerminalIndex>) ->
+            pretokens |> Set.iter (fun pretoken -> 
+                if not (acc.Contains(item0,pretoken)) then
+                    acc.Add(item0,pretoken) |> ignore
+                    let rsyms = rsyms_of_item0 item0 
+                    if rsyms.Length > 0 then 
+                        match rsyms.[0] with 
+                        | (PNonTerminal ntB) -> 
+                             let firstSet = ComputeFirstSetOfTokenList (Array.toList rsyms.[1..],pretoken)
+                             for prodIdx in prodTab.Productions.[ntB] do
+                                 addToWorkList (prodIdx_to_item0 prodIdx,firstSet)
+                        | PTerminal _ -> ()))
+        acc
+
+    // Compute the "spontaneous" and "propagate" maps for each LR(0) kernelItem 
+    //
+    // Input: The kernal K of a set of LR(0) items I and a grammar symbol X
+    //
+    // Output: The lookaheads generated spontaneously by items in I for kernel items 
+    // in goto(I,X) and the items I from which lookaheads are propagated to kernel
+    // items in goto(I,X)
+    //
+    // Method
+    //   1. Construct LR(0) kernel items (done - above)
+    //   2. 
+    // TODO: this is very, very slow. 
+    //
+    // PLAN TO OPTIMIZE THIS;
+    //   - Clarify and comment what's going on here
+    //   - verify if we really have to do these enormouos closure computations
+    //   - assess if it's possible to use the symbol we're looking for to help trim the jset
+    
+    reportTime(); printf "computing lookahead relations..."; stdout.Flush();
+
+        
+    let spontaneous, propagate  =
+        let closure1OfItem0WithDummy = 
+            Memoize (fun item0 -> ComputeClosure1 [(item0,Set.ofList [dummyLookaheadIdx])])
+
+        let spontaneous = new SpontaneousTable()
+        let propagate = new PropagateTable()
+        let count = ref 0 
+
+        for kernelIdx in kernelTab.Indexes do
+            printf  "."; stdout.Flush();
+            //printf  "kernelIdx = %d\n" kernelIdx; stdout.Flush();
+            let kernel = kernelTab.Kernel(kernelIdx)
+            for item0 in kernel do  
+                let item0Idx = KernelItemIdx(kernelIdx,item0)
+                let jset = closure1OfItem0WithDummy item0
+                //printf  "#jset = %d\n" jset.Count; stdout.Flush();
+                for (KeyValue(closureItem0, lookaheadTokens)) in jset.IEnumerable do
+                    incr count
+                    match rsym_of_item0 closureItem0 with 
+                    | None -> ()
+                    | Some rsym ->
+                         match gotoKernel (GotoItemIdx(kernelIdx,rsym)) with 
+                         | None -> ()
+                         | Some gotoKernelIdx ->
+                              let gotoItem = advance_of_item0 closureItem0
+                              let gotoItemIdx = KernelItemIdx(gotoKernelIdx,gotoItem)
+                              for lookaheadToken in lookaheadTokens do
+                                  if lookaheadToken = dummyLookaheadIdx 
+                                  then propagate.Add(item0Idx, gotoItemIdx) |> ignore
+                                  else spontaneous.Add(gotoItemIdx, lookaheadToken) |> ignore
+
+
+        //printfn "#kernelIdxs = %d, count = %d" kernelTab.Indexes.Length !count
+        spontaneous,
+        propagate
+   
+    //printfn "#spontaneous = %d, #propagate = %d" spontaneous.Count propagate.Count; stdout.Flush();
+   
+    //exit 0;
+    // Repeatedly use the "spontaneous" and "propagate" maps to build the full set 
+    // of lookaheads for each LR(0) kernelItem.   
+    reportTime(); printf  "building lookahead table..."; stdout.Flush();
+    let lookaheadTable = 
+
+        // Seed the table with the startKernelItems and the spontaneous info
+        let initialWork =
+            [ for idx in startKernelItemIdxs do
+                  yield (idx,endOfInputTerminalIdx)
+              for (KeyValue(kernelItemIdx,lookaheads)) in spontaneous.IEnumerable do
+                  for lookahead in lookaheads do
+                      yield (kernelItemIdx,lookahead) ]
+
+        let acc = new LookaheadTable()
+        // Compute the closure
+        ProcessWorkList 
+            initialWork
+            (fun queueWork (kernelItemIdx,lookahead) ->
+                acc.Add(kernelItemIdx,lookahead)
+                for gotoKernelIdx in propagate.[kernelItemIdx] do
+                    if not (acc.Contains(gotoKernelIdx,lookahead)) then 
+                        queueWork(gotoKernelIdx,lookahead))
+        acc
+
+    //printf  "built lookahead table, #lookaheads = %d\n" lookaheadTable.Count; stdout.Flush();
+
+    reportTime(); printf "building action table..."; stdout.Flush();
+    let shiftReduceConflicts = ref 0
+    let reduceReduceConflicts = ref 0
+    let actionTable, immediateActionTable = 
+
+        // Now build the action tables. First a utility to merge the given action  
+        // into the table, taking into account precedences etc. and reporting errors. 
+        let addResolvingPrecedence (arr: _[]) kernelIdx termIdx (precNew, actionNew) = 
+            // printf "DEBUG: state %d: adding action for %s, precNew = %a, actionNew = %a\n" kernelIdx (termTab.OfIndex termIdx) outputPrec precNew OutputAction actionNew; 
+            // We add in order of precedence - however the precedences may be the same, and we give warnings when rpecedence resolution is based on implicit file orderings 
+
+            let (precSoFar, actionSoFar) as itemSoFar = arr.[termIdx]
+
+            // printf "DEBUG: state %d: adding action for %s, precNew = %a, precSoFar = %a, actionSoFar = %a\n" kernelIdx (termTab.OfIndex termIdx) outputPrec precNew outputPrec precSoFar OutputAction actionSoFar; 
+            // if compare_prec precSoFar precNew = -1 then failwith "addResolvingPrecedence"; 
+
+            let itemNew = (precNew, actionNew) 
+            let winner = 
+                match itemSoFar,itemNew with 
+                | (_,Shift _),(_, Shift _) -> 
+                   if actionSoFar <> actionNew then 
+                      printf "internal error in fsyacc: shift/shift conflict";
+                   itemSoFar
+
+                | (((precShift,Shift _) as shiftItem), 
+                   ((precReduce,Reduce _) as reduceItem))
+                | (((precReduce,Reduce _) as reduceItem), 
+                   ((precShift,Shift _) as shiftItem)) -> 
+                    match precReduce, precShift with 
+                    | (ExplicitPrec (_,p1), ExplicitPrec(assocNew,p2)) -> 
+                      if p1 < p2 then shiftItem
+                      elif p1 > p2 then reduceItem
+                      else
+                        match precShift with 
+                        | ExplicitPrec(LeftAssoc,_) ->  reduceItem
+                        | ExplicitPrec(RightAssoc,_) -> shiftItem
+                        | _ ->
+                           printf "state %d: shift/reduce error on %s\n" kernelIdx (termTab.OfIndex termIdx); 
+                           incr shiftReduceConflicts;
+                           shiftItem
+                    | _ ->
+                       printf "state %d: shift/reduce error on %s\n" kernelIdx (termTab.OfIndex termIdx); 
+                       incr shiftReduceConflicts;
+                       shiftItem
+                | ((_,Reduce prodIdx1),(_, Reduce prodIdx2)) -> 
+                   printf "state %d: reduce/reduce error on %s\n" kernelIdx (termTab.OfIndex termIdx); 
+                   incr reduceReduceConflicts;
+                   if prodIdx1 < prodIdx2 then itemSoFar else itemNew
+                | _ -> itemNew 
+            arr.[termIdx] <- winner
+
+          
+        // This build the action table for one state. 
+        let ComputeActions kernelIdx = 
+            let kernel = kernelTab.Kernel kernelIdx
+            let arr = Array.create terminals.Length (NoPrecedence,Error)
+
+            //printf  "building lookahead table LR(1) items for kernelIdx %d\n" kernelIdx; stdout.Flush();
+
+            // Compute the LR(1) items based on lookaheads
+            let items = 
+                 [ for item0 in kernel do
+                     let kernelItemIdx = KernelItemIdx(kernelIdx,item0)
+                     let lookaheads = lookaheadTable.GetLookaheads(kernelItemIdx)
+                     yield (item0,lookaheads) ]
+                 |> ComputeClosure1
+
+            for (KeyValue(item0,lookaheads)) in items.IEnumerable do
+
+                let nonTermA = ntIdx_of_item0 item0
+                match rsym_of_item0 item0 with 
+                | Some (PTerminal termIdx) -> 
+                    let action =
+                      match gotoKernel (GotoItemIdx(kernelIdx,PTerminal termIdx)) with 
+                      | None -> failwith "action on terminal should have found a non-empty goto state"
+                      | Some gkernelItemIdx -> Shift gkernelItemIdx
+                    let prec = termTab.PrecInfoOfIndex termIdx
+                    addResolvingPrecedence arr kernelIdx termIdx (prec, action) 
+                | None ->
+                    for lookahead in lookaheads do
+                        if not (IsStartItem(item0)) then
+                            let prodIdx = prodIdx_of_item0 item0
+                            let prec = prec_of_item0 item0
+                            let action = (prec, Reduce prodIdx)
+                            addResolvingPrecedence arr kernelIdx lookahead action 
+                        elif lookahead = endOfInputTerminalIdx then
+                            let prec = prec_of_item0 item0
+                            let action = (prec,Accept)
+                            addResolvingPrecedence arr kernelIdx lookahead action 
+                        else ()
+                | _ -> ()
+
+            // If there is a single item A -> B C . and no Shift or Accept actions (i.e. only Error or Reduce, so the choice of terminal 
+            // cannot affect what we do) then we emit an immediate reduce action for the rule corresponding to that item 
+            // Also do the same for Accept rules. 
+            let closure = (ComputeClosure0 kernel)
+
+            let immediateAction =
+                match Set.toList closure with
+                | [item0] ->
+                    match (rsym_of_item0 item0) with 
+                    | None when (let reduceOrErrorAction = function Error | Reduce _ -> true | Shift _ | Accept -> false
+                                 termTab.Indexes |> List.forall(fun terminalIdx -> reduceOrErrorAction (snd(arr.[terminalIdx]))))
+                        -> Some (Reduce (prodIdx_of_item0 item0))
+
+                    | None when (let acceptOrErrorAction = function Error | Accept -> true | Shift _ | Reduce _ -> false
+                                 List.forall (fun terminalIdx -> acceptOrErrorAction (snd(arr.[terminalIdx]))) termTab.Indexes)
+                        -> Some Accept
+
+                    | _ -> None
+                | _ -> None
+
+            // A -> B C . rules give rise to reductions in favour of errors 
+            for item0 in ComputeClosure0 kernel do
+                let prec = prec_of_item0 item0
+                match rsym_of_item0 item0 with 
+                | None ->
+                    for terminalIdx in termTab.Indexes do 
+                        if snd(arr.[terminalIdx]) = Error then 
+                            let prodIdx = prodIdx_of_item0 item0
+                            let action = (prec, (if IsStartItem(item0) then Accept else Reduce prodIdx))
+                            addResolvingPrecedence arr kernelIdx terminalIdx action
+                | _  -> ()
+
+            arr,immediateAction
+
+        let actionInfo = List.map ComputeActions kernelTab.Indexes
+        Array.ofList (List.map fst actionInfo),
+        Array.ofList (List.map snd actionInfo)
+
+    // The goto table is much simpler - it is based on LR(0) kernels alone. 
+
+    reportTime(); printf  "building goto table..."; stdout.Flush();
+    let gotoTable = 
+         let gotos kernelIdx = Array.ofList (List.map (fun nt -> gotoKernel (GotoItemIdx(kernelIdx,PNonTerminal nt))) ntTab.Indexes)
+         Array.ofList (List.map gotos kernelTab.Indexes)
+
+    reportTime(); printfn  "returning tables."; stdout.Flush();
+    if !shiftReduceConflicts > 0 then printfn  "%d shift/reduce conflicts" !shiftReduceConflicts; stdout.Flush();
+    if !reduceReduceConflicts > 0 then printfn  "%d reduce/reduce conflicts" !reduceReduceConflicts; stdout.Flush();
+
+    /// The final results
+    let states = kernels |> Array.ofList 
+    let prods = Array.ofList (List.map (fun (Production(nt,prec,syms,code)) -> (nt, ntTab.ToIndex nt, syms,code)) prods)
+
+    logf (fun logStream -> 
+        printf  "writing tables to log\n"; stdout.Flush();
+        OutputLalrTables logStream     (prods, states, startKernelIdxs, actionTable, immediateActionTable, gotoTable, (termTab.ToIndex endOfInputTerminal), errorTerminalIdx));
+
+    let states = states |> Array.map (Set.toList >> List.map prodIdx_of_item0)
+    (prods, states, startKernelIdxs, 
+     actionTable, immediateActionTable, gotoTable, 
+     (termTab.ToIndex endOfInputTerminal), 
+     errorTerminalIdx, nonTerminals)
+
+  
+(* Some examples for testing *)  
+
+(*
+
+let example1 = 
+  let e = "E" 
+  let t = "Terminal"
+  let plus = "+"
+  let mul = "*"
+  let f = "F"
+  let lparen = "("
+  let rparen = ")"
+  let id = "id"
+  
+  let terminals = [plus; mul; lparen; rparen; id]
+  let nonTerminals = [e; t; f]
+  
+  let p2 = e, (NonAssoc, ExplicitPrec 1), [NonTerminal e; Terminal plus; NonTerminal t], None
+  let p3 = e, (NonAssoc, ExplicitPrec 2), [NonTerminal t], None in  
+  let p4 = t, (NonAssoc, ExplicitPrec 3), [NonTerminal t; Terminal mul; NonTerminal f], None
+  let p5 = t, (NonAssoc, ExplicitPrec 4), [NonTerminal f], None
+  let p6 = f, (NonAssoc, ExplicitPrec  5), [Terminal lparen; NonTerminal e; Terminal rparen], None
+  let p7 = f, (NonAssoc, ExplicitPrec 6), [Terminal id], None
+
+  let prods = [p2;p3;p4;p5;p6;p7]
+  Spec(terminals,nonTerminals,prods, [e])
+
+let example2 = 
+  let prods = [ "S", (NonAssoc, ExplicitPrec 1), [NonTerminal "C";NonTerminal "C"], None; 
+                "C", (NonAssoc, ExplicitPrec 2), [Terminal "c";NonTerminal "C"], None ;
+                "C", (NonAssoc, ExplicitPrec 3), [Terminal "d"] , None  ]in
+  Spec(["c";"d"],["S";"C"],prods, ["S"])
+
+let example3 = 
+  let terminals = ["+"; "*"; "("; ")"; "id"]
+  let nonTerminals = ["E"; "Terminal"; "E'"; "F"; "Terminal'"]
+  let prods = [ "E", (NonAssoc, ExplicitPrec 1), [ NonTerminal "Terminal"; NonTerminal "E'" ], None;
+                "E'", (NonAssoc, ExplicitPrec 2), [ Terminal "+"; NonTerminal "Terminal"; NonTerminal "E'"], None;
+                "E'", (NonAssoc, ExplicitPrec 3), [ ], None;
+                "Terminal", (NonAssoc, ExplicitPrec 4), [ NonTerminal "F"; NonTerminal "Terminal'" ], None;
+                "Terminal'", (NonAssoc, ExplicitPrec 5), [ Terminal "*"; NonTerminal "F"; NonTerminal "Terminal'"], None;
+                "Terminal'", (NonAssoc, ExplicitPrec 6), [ ], None;
+                "F", (NonAssoc, ExplicitPrec 7), [ Terminal "("; NonTerminal "E"; Terminal ")"], None;
+                "F", (NonAssoc, ExplicitPrec 8), [ Terminal "id"], None ]
+  Spec(terminals,nonTerminals,prods, ["E"])
+
+let example4 = 
+  let terminals = ["+"; "*"; "("; ")"; "id"]
+  let nonTerminals = ["E"]
+  let prods = [ "E", (NonAssoc, ExplicitPrec 1), [ NonTerminal "E"; Terminal "+"; NonTerminal "E" ], None;
+                "E", (NonAssoc, ExplicitPrec 2), [ NonTerminal "E"; Terminal "*"; NonTerminal "E" ], None;
+                "E", (NonAssoc, ExplicitPrec 3), [ Terminal "("; NonTerminal "E"; Terminal ")"], None;
+                "E", (NonAssoc, ExplicitPrec 8), [ Terminal "id"],  None ]
+  Spec(terminals,nonTerminals,prods, ["E"])
+
+let example5 = 
+  let terminals = ["+"; "*"; "("; ")"; "id"]
+  let nonTerminals = ["E"]
+  let prods = [ "E", (NonAssoc, ExplicitPrec 1), [ NonTerminal "E"; Terminal "+"; NonTerminal "E" ], None;
+                "E", (NonAssoc, ExplicitPrec 2), [ NonTerminal "E"; Terminal "*"; NonTerminal "E" ], None;
+                "E", (NonAssoc, ExplicitPrec 3), [ Terminal "("; NonTerminal "E"; Terminal ")"], None;
+                "E", (NonAssoc, ExplicitPrec 8), [ Terminal "id"], None ]
+  Spec(terminals,nonTerminals,prods, ["E"])
+
+let example6 = 
+  let terminals = ["+"; "*"; "("; ")"; "id"; "-"]
+  let nonTerminals = ["E"]
+  let prods = [ "E", (RightAssoc, ExplicitPrec 1), [ NonTerminal "E"; Terminal "-"; NonTerminal "E" ], None;
+                "E", (LeftAssoc, ExplicitPrec 1), [ NonTerminal "E"; Terminal "+"; NonTerminal "E" ], None;
+                "E", (LeftAssoc, ExplicitPrec 2), [ NonTerminal "E"; Terminal "*"; NonTerminal "E" ], None;
+                "E", (NonAssoc, ExplicitPrec 3), [ Terminal "("; NonTerminal "E"; Terminal ")"], None;
+                "E", (NonAssoc, ExplicitPrec 8), [ Terminal "id"], None ]
+  Spec(terminals,nonTerminals,prods, ["E"])
+
+
+let example7 = 
+  let prods = [ "S", (NonAssoc, ExplicitPrec 1), [NonTerminal "L";Terminal "="; NonTerminal "R"], None; 
+                "S", (NonAssoc, ExplicitPrec 2), [NonTerminal "R"], None ;
+                "L", (NonAssoc, ExplicitPrec 3), [Terminal "*"; NonTerminal "R"], None;
+                "L", (NonAssoc, ExplicitPrec 3), [Terminal "id"], None; 
+                "R", (NonAssoc, ExplicitPrec 3), [NonTerminal "L"], None; ]
+  Spec(["*";"=";"id"],["S";"L";"R"],prods, ["S"])
+
+
+
+let test ex = CompilerLalrParserSpec stdout ex
+
+(* let _ = test example2*)
+(* let _ = exit 1*)
+(* let _ = test example3 
+let _ = test example1  
+let _ = test example4
+let _ = test example5
+let _ = test example6 *)
+*)
--- fsharp-3.1.1.26+dfsg2.orig/FsYacc/fsyacclex.fsl
+++ fsharp-3.1.1.26+dfsg2/FsYacc/fsyacclex.fsl
@@ -1,144 +1,144 @@
-{
-(* (c) Microsoft Corporation 2005-2008.  *)
-
-module internal FSharp.PowerPack.FsYacc.Lexer
-  
-open FSharp.PowerPack.FsYacc.AST
-open FSharp.PowerPack.FsYacc.Parser
-open System.Text
-open Internal.Utilities.Text.Lexing
-
-let lexeme  (lexbuf : LexBuffer<char>) = new System.String(lexbuf.Lexeme)
-let newline (lexbuf:LexBuffer<_>) = lexbuf.EndPos <- lexbuf.EndPos.NextLine
-
-let unexpected_char lexbuf =
-  failwith ("Unexpected character '"+(lexeme lexbuf)+"'")
-
-let typeDepth = ref 0
-let startPos = ref Position.Empty
-let mutable str_buf = new System.Text.StringBuilder()
-
-let appendBuf (str:string) = str_buf.Append str |> ignore
-let clearBuf () = str_buf <- new System.Text.StringBuilder()
-
-} 
-
-let letter = ['A'-'Z'] | ['a'-'z']
-let digit = ['0'-'9']
-let whitespace = [' ' '\t']
-let newline = ('\n' | '\r' '\n')
-let ident_start_char = letter       
-let ident_char = ( ident_start_char| digit | ['\'' '_'] )
-let ident = ident_start_char ident_char*
-
-rule token = parse
- | "%{" { let p = lexbuf.StartPos in header p (new StringBuilder 100) lexbuf }
- | "%%" { PERCENT_PERCENT }
- | "%token" (whitespace* '<') { typeDepth := 1; startPos := lexbuf.StartPos; clearBuf(); TOKEN (fs_type lexbuf) }
- | "%token" { TOKEN (None) }
- | "%start"{ START }
- | "%prec"{ PREC }
- | "%type" (whitespace* '<') { typeDepth := 1; startPos := lexbuf.StartPos; clearBuf(); TYPE (match fs_type lexbuf with Some x -> x | None -> failwith "gettype") }
- | "%left" { LEFT }
- | "%right" { RIGHT }
- | "%nonassoc" { NONASSOC }
- | "error" { ERROR }
- | '<' { LESS }
- | '>' { GREATER }
- | ';' { SEMI }
- | '{' { let p = lexbuf.StartPos in 
-         let buff = (new StringBuilder 100) in
-         // adjust the first line to get even indentation for all lines w.r.t. the left hand margin
-         buff.Append (String.replicate (lexbuf.StartPos.Column+1) " ")  |> ignore;
-         code p buff lexbuf }
- | whitespace+  { token lexbuf }
- | newline { newline lexbuf; token lexbuf }
- | ident_start_char ident_char* { IDENT (lexeme lexbuf) }
- | '|' { BAR }
- | "/*" { ignore(comment lexbuf); token lexbuf }
- | "//" [^'\n''\r']* {  token lexbuf  }
- | ':' { COLON }
- | _ { unexpected_char lexbuf }     
- | eof { EOF  }  
-
-and fs_type = parse
-  | '<' { incr typeDepth; appendBuf(lexeme lexbuf); fs_type lexbuf}
-  | '>'
-    { decr typeDepth; 
-      if !typeDepth = 0
-      then Some(string str_buf) 
-      else appendBuf(lexeme lexbuf); fs_type lexbuf }
-  | _ { appendBuf(lexeme lexbuf); fs_type lexbuf } 
-                                   
-and header p buff = parse
- | "%}" { HEADER (buff.ToString(), p) }
- | newline { newline lexbuf; 
-             ignore <| buff.Append System.Environment.NewLine; 
-             header p buff lexbuf }
- | (whitespace | letter | digit) +  
-      { ignore <| buff.Append (lexeme lexbuf); 
-        header p buff lexbuf }
- | "//" [^'\n''\r']*
-      { ignore <| buff.Append (lexeme lexbuf); 
-        header p buff lexbuf }
- | "'\"'" | "'\\\"'"
-      { ignore <| buff.Append (lexeme lexbuf); 
-        header p buff lexbuf }
- | "\"" 
-      { ignore <| buff.Append (lexeme lexbuf); 
-        ignore(codestring buff lexbuf); 
-        header p buff lexbuf }
- | eof { EOF }
- | _ { ignore <| buff.Append(lexeme lexbuf).[0]; 
-       header p buff lexbuf }
-and code p buff = parse
- | "}" { CODE (buff.ToString(), p) }
- | "{" { ignore <| buff.Append (lexeme lexbuf); 
-         ignore(code p buff lexbuf); 
-         ignore <| buff.Append "}"; 
-         code p buff lexbuf }
- | newline { newline lexbuf; 
-             ignore <| buff.Append System.Environment.NewLine; 
-             code p buff lexbuf }
- | "'\"'" | "'\\\"'"
-      { ignore <| buff.Append (lexeme lexbuf); 
-        code p buff lexbuf }
- | "\"" { ignore <| buff.Append (lexeme lexbuf); 
-          ignore(codestring buff lexbuf); 
-          code p buff lexbuf }
- | (whitespace | letter | digit) +  
-   { ignore <| buff.Append (lexeme lexbuf); 
-     code p buff lexbuf }
- | "//" [^'\n''\r']*
-   { ignore <| buff.Append (lexeme lexbuf); 
-     code p buff lexbuf }
- | eof { EOF }
- | _ { ignore <| buff.Append(lexeme lexbuf).[0]; 
-       code p buff lexbuf }
-
-
-and codestring buff = parse
- |  '\\' ('"' | '\\')
-   { ignore <| buff.Append (lexeme lexbuf); 
-     codestring buff lexbuf } 
- | '"' { ignore <| buff.Append (lexeme lexbuf); 
-         buff.ToString() }
- | newline { newline lexbuf; 
-             ignore <| buff.Append System.Environment.NewLine; 
-             codestring buff lexbuf }
- | (whitespace | letter | digit) +  
-   { ignore <| buff.Append (lexeme lexbuf); 
-     codestring buff lexbuf }
- | eof { failwith "unterminated string in code" }
- | _ { ignore <| buff.Append(lexeme lexbuf).[0]; 
-       codestring buff lexbuf }
-
-
-and comment = parse
- | "/*" { ignore(comment lexbuf); comment lexbuf }
- | newline { newline lexbuf; comment lexbuf }
- | "*/" { () }
- | eof { failwith "end of file in comment" }
- | [^ '/' '*' '\n' '\r' '"' '/' ]+  { comment lexbuf }
- | _  { comment lexbuf }
-
+{
+(* (c) Microsoft Corporation 2005-2008.  *)
+
+module internal FSharp.PowerPack.FsYacc.Lexer
+  
+open FSharp.PowerPack.FsYacc.AST
+open FSharp.PowerPack.FsYacc.Parser
+open System.Text
+open Internal.Utilities.Text.Lexing
+
+let lexeme  (lexbuf : LexBuffer<char>) = new System.String(lexbuf.Lexeme)
+let newline (lexbuf:LexBuffer<_>) = lexbuf.EndPos <- lexbuf.EndPos.NextLine
+
+let unexpected_char lexbuf =
+  failwith ("Unexpected character '"+(lexeme lexbuf)+"'")
+
+let typeDepth = ref 0
+let startPos = ref Position.Empty
+let mutable str_buf = new System.Text.StringBuilder()
+
+let appendBuf (str:string) = str_buf.Append str |> ignore
+let clearBuf () = str_buf <- new System.Text.StringBuilder()
+
+} 
+
+let letter = ['A'-'Z'] | ['a'-'z']
+let digit = ['0'-'9']
+let whitespace = [' ' '\t']
+let newline = ('\n' | '\r' '\n')
+let ident_start_char = letter       
+let ident_char = ( ident_start_char| digit | ['\'' '_'] )
+let ident = ident_start_char ident_char*
+
+rule token = parse
+ | "%{" { let p = lexbuf.StartPos in header p (new StringBuilder 100) lexbuf }
+ | "%%" { PERCENT_PERCENT }
+ | "%token" (whitespace* '<') { typeDepth := 1; startPos := lexbuf.StartPos; clearBuf(); TOKEN (fs_type lexbuf) }
+ | "%token" { TOKEN (None) }
+ | "%start"{ START }
+ | "%prec"{ PREC }
+ | "%type" (whitespace* '<') { typeDepth := 1; startPos := lexbuf.StartPos; clearBuf(); TYPE (match fs_type lexbuf with Some x -> x | None -> failwith "gettype") }
+ | "%left" { LEFT }
+ | "%right" { RIGHT }
+ | "%nonassoc" { NONASSOC }
+ | "error" { ERROR }
+ | '<' { LESS }
+ | '>' { GREATER }
+ | ';' { SEMI }
+ | '{' { let p = lexbuf.StartPos in 
+         let buff = (new StringBuilder 100) in
+         // adjust the first line to get even indentation for all lines w.r.t. the left hand margin
+         buff.Append (String.replicate (lexbuf.StartPos.Column+1) " ")  |> ignore;
+         code p buff lexbuf }
+ | whitespace+  { token lexbuf }
+ | newline { newline lexbuf; token lexbuf }
+ | ident_start_char ident_char* { IDENT (lexeme lexbuf) }
+ | '|' { BAR }
+ | "/*" { ignore(comment lexbuf); token lexbuf }
+ | "//" [^'\n''\r']* {  token lexbuf  }
+ | ':' { COLON }
+ | _ { unexpected_char lexbuf }     
+ | eof { EOF  }  
+
+and fs_type = parse
+  | '<' { incr typeDepth; appendBuf(lexeme lexbuf); fs_type lexbuf}
+  | '>'
+    { decr typeDepth; 
+      if !typeDepth = 0
+      then Some(string str_buf) 
+      else appendBuf(lexeme lexbuf); fs_type lexbuf }
+  | _ { appendBuf(lexeme lexbuf); fs_type lexbuf } 
+                                   
+and header p buff = parse
+ | "%}" { HEADER (buff.ToString(), p) }
+ | newline { newline lexbuf; 
+             ignore <| buff.Append System.Environment.NewLine; 
+             header p buff lexbuf }
+ | (whitespace | letter | digit) +  
+      { ignore <| buff.Append (lexeme lexbuf); 
+        header p buff lexbuf }
+ | "//" [^'\n''\r']*
+      { ignore <| buff.Append (lexeme lexbuf); 
+        header p buff lexbuf }
+ | "'\"'" | "'\\\"'"
+      { ignore <| buff.Append (lexeme lexbuf); 
+        header p buff lexbuf }
+ | "\"" 
+      { ignore <| buff.Append (lexeme lexbuf); 
+        ignore(codestring buff lexbuf); 
+        header p buff lexbuf }
+ | eof { EOF }
+ | _ { ignore <| buff.Append(lexeme lexbuf).[0]; 
+       header p buff lexbuf }
+and code p buff = parse
+ | "}" { CODE (buff.ToString(), p) }
+ | "{" { ignore <| buff.Append (lexeme lexbuf); 
+         ignore(code p buff lexbuf); 
+         ignore <| buff.Append "}"; 
+         code p buff lexbuf }
+ | newline { newline lexbuf; 
+             ignore <| buff.Append System.Environment.NewLine; 
+             code p buff lexbuf }
+ | "'\"'" | "'\\\"'"
+      { ignore <| buff.Append (lexeme lexbuf); 
+        code p buff lexbuf }
+ | "\"" { ignore <| buff.Append (lexeme lexbuf); 
+          ignore(codestring buff lexbuf); 
+          code p buff lexbuf }
+ | (whitespace | letter | digit) +  
+   { ignore <| buff.Append (lexeme lexbuf); 
+     code p buff lexbuf }
+ | "//" [^'\n''\r']*
+   { ignore <| buff.Append (lexeme lexbuf); 
+     code p buff lexbuf }
+ | eof { EOF }
+ | _ { ignore <| buff.Append(lexeme lexbuf).[0]; 
+       code p buff lexbuf }
+
+
+and codestring buff = parse
+ |  '\\' ('"' | '\\')
+   { ignore <| buff.Append (lexeme lexbuf); 
+     codestring buff lexbuf } 
+ | '"' { ignore <| buff.Append (lexeme lexbuf); 
+         buff.ToString() }
+ | newline { newline lexbuf; 
+             ignore <| buff.Append System.Environment.NewLine; 
+             codestring buff lexbuf }
+ | (whitespace | letter | digit) +  
+   { ignore <| buff.Append (lexeme lexbuf); 
+     codestring buff lexbuf }
+ | eof { failwith "unterminated string in code" }
+ | _ { ignore <| buff.Append(lexeme lexbuf).[0]; 
+       codestring buff lexbuf }
+
+
+and comment = parse
+ | "/*" { ignore(comment lexbuf); comment lexbuf }
+ | newline { newline lexbuf; comment lexbuf }
+ | "*/" { () }
+ | eof { failwith "end of file in comment" }
+ | [^ '/' '*' '\n' '\r' '"' '/' ]+  { comment lexbuf }
+ | _  { comment lexbuf }
+
--- fsharp-3.1.1.26+dfsg2.orig/FsYacc/fsyaccpars.fsy
+++ fsharp-3.1.1.26+dfsg2/FsYacc/fsyaccpars.fsy
@@ -1,55 +1,55 @@
-%{
-(* (c) Microsoft Corporation 2005-2008.  *)
-
-// FSharp.PowerPack.FsYacc.Parser
-
-open FSharp.PowerPack.FsYacc
-open FSharp.PowerPack.FsYacc.AST
-
-#nowarn "62" // This construct is for ML compatibility
-
-%} 
-
-%type <AST.ParserSpec> spec
-%token <string>  IDENT 
-%token <AST.Code> HEADER CODE 
-%token BAR PERCENT_PERCENT  START LEFT RIGHT NONASSOC LESS GREATER COLON PREC SEMI EOF ERROR
-%token <string> TYPE
-%token <string option> TOKEN
-%start spec
-%left BAR
-%%      
-
-spec: 
-    headeropt decls PERCENT_PERCENT rules 
-    { List.foldBack (fun f x -> f x) $2 { Header=$1;Tokens=[];Types=[];Associativities=[];StartSymbols=[];Rules=$4 } }
-
-headeropt: 
-  | HEADER 
-       { $1 } 
-  | 
-      { "", (parseState.ResultRange |> fst)}
-
-decls:  
-    { [] } 
-  | decl decls { $1 :: $2 }
-
-decl: 
-    TOKEN idents { (fun x -> {x with Tokens = x.Tokens @ (List.map (fun x -> (x,$1)) $2)}) }
-  | TYPE idents   { (fun x -> {x with Types = x.Types @ (List.map (fun x -> (x,$1)) $2)} ) } 
-  | START idents   { (fun x -> {x with StartSymbols = x.StartSymbols @ $2} ) }
-  | LEFT idents   { (fun x -> {x with Associativities = x.Associativities @ [(List.map (fun x -> (x,LeftAssoc)) $2)]} ) }
-  | RIGHT idents   { (fun x -> {x with Associativities = x.Associativities @ [(List.map (fun x -> (x,RightAssoc)) $2)]} ) }
-  | NONASSOC idents   { (fun x -> {x with Associativities = x.Associativities @ [(List.map (fun x -> (x,NonAssoc)) $2)]} ) }
-
-idents: IDENT idents { $1 :: $2 } | { [] }
-rules: rule rules { $1 :: $2 } | rule { [$1] }
-rule: IDENT COLON optbar clauses optsemi { ($1,$4) }
-optbar: { } | BAR { }
-optsemi: { } | SEMI { }
-clauses: clause BAR clauses {$1 :: $3 } | clause { [$1] }
-clause: syms optprec CODE { Rule($1,$2,Some $3) }
-syms: IDENT syms { $1 :: $2 } | ERROR syms { "error" :: $2 } | { [] }
-optprec: { None } | PREC IDENT { Some $2 }
-
-
+%{
+(* (c) Microsoft Corporation 2005-2008.  *)
+
+// FSharp.PowerPack.FsYacc.Parser
+
+open FSharp.PowerPack.FsYacc
+open FSharp.PowerPack.FsYacc.AST
+
+#nowarn "62" // This construct is for ML compatibility
+
+%} 
+
+%type <AST.ParserSpec> spec
+%token <string>  IDENT 
+%token <AST.Code> HEADER CODE 
+%token BAR PERCENT_PERCENT  START LEFT RIGHT NONASSOC LESS GREATER COLON PREC SEMI EOF ERROR
+%token <string> TYPE
+%token <string option> TOKEN
+%start spec
+%left BAR
+%%      
+
+spec: 
+    headeropt decls PERCENT_PERCENT rules 
+    { List.foldBack (fun f x -> f x) $2 { Header=$1;Tokens=[];Types=[];Associativities=[];StartSymbols=[];Rules=$4 } }
+
+headeropt: 
+  | HEADER 
+       { $1 } 
+  | 
+      { "", (parseState.ResultRange |> fst)}
+
+decls:  
+    { [] } 
+  | decl decls { $1 :: $2 }
+
+decl: 
+    TOKEN idents { (fun x -> {x with Tokens = x.Tokens @ (List.map (fun x -> (x,$1)) $2)}) }
+  | TYPE idents   { (fun x -> {x with Types = x.Types @ (List.map (fun x -> (x,$1)) $2)} ) } 
+  | START idents   { (fun x -> {x with StartSymbols = x.StartSymbols @ $2} ) }
+  | LEFT idents   { (fun x -> {x with Associativities = x.Associativities @ [(List.map (fun x -> (x,LeftAssoc)) $2)]} ) }
+  | RIGHT idents   { (fun x -> {x with Associativities = x.Associativities @ [(List.map (fun x -> (x,RightAssoc)) $2)]} ) }
+  | NONASSOC idents   { (fun x -> {x with Associativities = x.Associativities @ [(List.map (fun x -> (x,NonAssoc)) $2)]} ) }
+
+idents: IDENT idents { $1 :: $2 } | { [] }
+rules: rule rules { $1 :: $2 } | rule { [$1] }
+rule: IDENT COLON optbar clauses optsemi { ($1,$4) }
+optbar: { } | BAR { }
+optsemi: { } | SEMI { }
+clauses: clause BAR clauses {$1 :: $3 } | clause { [$1] }
+clause: syms optprec CODE { Rule($1,$2,Some $3) }
+syms: IDENT syms { $1 :: $2 } | ERROR syms { "error" :: $2 } | { [] }
+optprec: { None } | PREC IDENT { Some $2 }
+
+
