DefaultApp - Make OnRegisterCustomSchemes virtual

Can be overridden

--- CefSharp/DefaultApp.cs
+++ CefSharp/DefaultApp.cs
@@ -25,7 +25,7 @@
             OnRegisterCustomSchemes(registrar);
         }

-        protected void OnRegisterCustomSchemes(ISchemeRegistrar registrar)
+        protected virtual void OnRegisterCustomSchemes(ISchemeRegistrar registrar)
         {
             foreach (var scheme in Schemes)
             {


Ticket 106 : Add friend assembly

Ticket 106 : Add friend assembly

--- SimpleIdentityServer/src/SimpleIdentityServer.Core/Properties/AssemblyInfo.cs
+++ SimpleIdentityServer/src/SimpleIdentityServer.Core/Properties/AssemblyInfo.cs
@@ -1,51 +1,52 @@
-#region copyright
-// Copyright 2015 Habart Thierry
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-#endregion
-using System.Reflection;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-
-// General Information about an assembly is controlled through the following
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-[assembly: AssemblyTitle("SimpleIdentityServer.Core")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("SimpleIdentityServer.Core")]
-[assembly: AssemblyCopyright("Copyright ©  2015")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-// Setting ComVisible to false makes the types in this assembly not visible
-// to COM components.  If you need to access a type in this assembly from
-// COM, set the ComVisible attribute to true on that type.
-[assembly: ComVisible(false)]
-
-// The following GUID is for the ID of the typelib if this project is exposed to COM
-[assembly: Guid("3d519f94-39f1-45f5-b080-b2d719021a10")]
-
-// Version information for an assembly consists of the following four values:
-//
-//      Major Version
-//      Minor Version
-//      Build Number
-//      Revision
-//
-// You can specify all the values or you can default the Build and Revision Numbers
-// by using the '*' as shown below:
-// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]
+#region copyright
+// Copyright 2015 Habart Thierry
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+#endregion
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("SimpleIdentityServer.Core")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("SimpleIdentityServer.Core")]
+[assembly: AssemblyCopyright("Copyright ©  2015")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components.  If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("3d519f94-39f1-45f5-b080-b2d719021a10")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
+[assembly: InternalsVisibleTo("SimpleIdentityServer.Core.UnitTests")]


use dictionary for basic block lookup speed

--- PEAnalyzer/PEFile.cs
+++ PEAnalyzer/PEFile.cs
@@ -24,6 +24,7 @@
         private byte[] rdata;
         private List<DiscoveredString> discoveredStrings = new List<DiscoveredString>();
         private List<DiscoveredReference> discoveredReferences = new List<DiscoveredReference>();
+        private ulong functionByteAlignment;

         #endregion

@@ -868,10 +869,13 @@

             public byte[] Code { get; private set; }

-            public CodeChunk(ulong offset, ulong length)
+            public bool EndsOnAlignmentBoundary { get; private set; }
+
+            public CodeChunk(ulong offset, ulong length, bool endsOnAlignmentBoundary)
             {
                 this.Offset = offset;
                 this.Code = new byte[length];
+                this.EndsOnAlignmentBoundary = endsOnAlignmentBoundary;
             }
         }

@@ -885,7 +889,6 @@
             byte[] alignmentBytes = new byte[] { 0x90, 0xcc };
             ulong minimumByteSequenceLength = 1;
             HashSet<AlignmentByteSequence> alignmentSequences = new HashSet<AlignmentByteSequence>();
-            ulong functionByteAlignment = 0;

             for (ulong i = 0; i < (ulong)this.code.Length - minimumByteSequenceLength; ++i)
             {
@@ -951,32 +954,20 @@
                 // aligmnent boundary has been passed.
                 if (percentDifference > 45.0)
                 {
-                    functionByteAlignment = thisPossibleAlignment;
+                    this.functionByteAlignment = thisPossibleAlignment;
                     break;
                 }
             }

             // If we were unable to determine the most likely byte alignment value, then use a standard Microsoft 16
             // byte aligment value.
-            if (functionByteAlignment == 0)
-            {
-                functionByteAlignment = 16;
+            if (this.functionByteAlignment == 0)
+            {
+                this.functionByteAlignment = 16;
             }

             // Remove any aligment sequences that do not end on the aligment boundary.
-            alignmentSequences.RemoveWhere(x => x.NextInstructionOffset % functionByteAlignment != 0);
-
-            int counter = 0;
-            foreach (AlignmentByteSequence sequence in alignmentSequences)
-            {
-                if (counter++ > 5)
-                {
-                    break;
-                }
-
-                Console.WriteLine("next instruction: " + sequence.NextInstructionOffset.ToAddressString32());
-                Console.WriteLine("length:           " + sequence.Length);
-            }
+            alignmentSequences.RemoveWhere(x => x.NextInstructionOffset % this.functionByteAlignment != 0);

             return alignmentSequences;
         }
@@ -992,7 +983,14 @@
             {
                 // Copy the code to a code chunk.
                 ulong codeChunkLength = sequence.Offset - currentOffset;
-                CodeChunk cc = new CodeChunk(currentOffset, codeChunkLength);
+                bool endsOnAlignmentBoundary = ((currentOffset + codeChunkLength + 1) % this.functionByteAlignment) == 0;
+                if (endsOnAlignmentBoundary)
+                {
+                    Console.WriteLine();
+                }
+
+                // TODO: ***IMPORTANT*** merge with next code chunk if this one ends on an alignment boundary.
+                CodeChunk cc = new CodeChunk(currentOffset, codeChunkLength, endsOnAlignmentBoundary);
                 Array.Copy(this.code, (long)currentOffset, cc.Code, 0, (long)codeChunkLength);
                 codeChunks.Add(cc);

@@ -1003,26 +1001,25 @@
             return codeChunks;
         }

-        private BasicBlock GetBasicBlockOrCreateNewBasicBlock(HashSet<BasicBlock> basicBlocks, ulong address)
-        {
-            // Create a new basic block.
-            BasicBlock bb = new BasicBlock(address);
-
-            // Add it to the set of basic blocks.
-            if (!basicBlocks.Add(bb))
-            {
-                // If it already existed, then return the pre-existing basic block.
-                return basicBlocks.First(x => x.FirstInstructionAddress == bb.FirstInstructionAddress);
+        private BasicBlock GetBasicBlockOrCreateNewBasicBlock(Dictionary<ulong, BasicBlock> basicBlocks, ulong address)
+        {
+            // See if the basic block already exists.
+            if (basicBlocks.ContainsKey(address))
+            {
+                // If it already exists, then return it.
+                return basicBlocks[address];
             }
             else
             {
-                // If it did not already exist, return the newly created basic block.
+                // Otherwise, create a new basic block, add it, and return it.
+                BasicBlock bb = new BasicBlock(address);
+                basicBlocks[address] = bb;
                 return bb;
             }
         }

         // Add basic blocks based on control flow transitions.
-        private void AddBasicBlocksFromInstructions(HashSet<BasicBlock> basicBlocks, List<Instruction> instructions)
+        private void AddBasicBlocksFromInstructions(Dictionary<ulong, BasicBlock> basicBlocks, List<Instruction> instructions)
         {
             // Start the first basic block.
             BasicBlock bb = null;
@@ -1103,31 +1100,53 @@
             d.Engine = Disassembler.InternalDisassembler.BeaEngine;
             d.TargetArchitecture = Disassembler.Architecture.x86_32;
             List<Instruction> instructions = new List<Instruction>();
-            HashSet<BasicBlock> basicBlocks = new HashSet<BasicBlock>();
+            Dictionary<ulong, BasicBlock> basicBlocks = new Dictionary<ulong, BasicBlock>();

             // For each code chunk, disassemble it and find basic blocks.
             foreach (CodeChunk cc in codeChunks)
             {
                 ulong virtualAddressBase = this.ImageBase + this.BaseOfCodeInMemory + cc.Offset;
-                instructions = new List<Instruction>(d.DisassembleInstructions(cc.Code, virtualAddressBase));
+                List<Instruction> codeChunkInstructions = new List<Instruction>(d.DisassembleInstructions(cc.Code, virtualAddressBase));

                 // If no instructions were found or if the last instruction has no control flow, then it is likely
                 // that decoding failed and that this is actually a data chunk.
-                if (instructions.Count == 0 || instructions.Last().FlowType == Instruction.ControlFlow.None)
+                if (codeChunkInstructions.Count == 0 ||
+                    !cc.EndsOnAlignmentBoundary && (codeChunkInstructions.Last().FlowType == Instruction.ControlFlow.None))
                 {
                     // TODO: track data chunks.
-                    Console.WriteLine("This is a data chunk.");
                     continue;
                 }
                 else
                 {
+                    if (cc.EndsOnAlignmentBoundary && codeChunkInstructions.Last().FlowType == Instruction.ControlFlow.None)
+                    {
+                        Console.WriteLine();
+                    }
+
                     // If the last instruction has some type of flow control, then it is likely that this code chunk
                     // was filled with valid code. Add all basic blocks from the disassembled list of instructions.
-                    this.AddBasicBlocksFromInstructions(basicBlocks, instructions);
-                }
-            }
-
-            List<BasicBlock> sortedBasicBlocks = basicBlocks.OrderBy(x => x.FirstInstructionAddress).ToList();
+                    this.AddBasicBlocksFromInstructions(basicBlocks, codeChunkInstructions);
+
+                    // Add instructions to the global list of instructions.
+                    instructions.AddRange(codeChunkInstructions);
+                }
+            }
+
+            // Iterate through all the verified valid instructions and add them to their respective basic blocks.
+            BasicBlock currentBasicBlock = null;
+            foreach (Instruction i in instructions)
+            {
+                if (basicBlocks.ContainsKey(i.Address))
+                {
+                    currentBasicBlock = basicBlocks[i.Address];
+                }
+
+                currentBasicBlock.Instructions.Add(i);
+            }
+
+            List<BasicBlock> sortedBasicBlocks = basicBlocks.Values.OrderBy(x => x.FirstInstructionAddress).ToList();
+
+            Console.WriteLine();

             /*
             // Search for address references in rdata.
@@ -1183,276 +1202,6 @@
                     }
                 }
             }
-
-            // TODO: see why some basic blocks occur outside of the premissible range of addresses.
-
-            // Get the last instruction found in the code section.
-            List<Instruction> sortedInstructions = instructions.OrderBy(x => x.Address).ToList();
-            Instruction firstInstruction = sortedInstructions.FirstOrDefault();
-            Instruction lastInstruction = sortedInstructions.LastOrDefault();
-            ulong firstPermissibleAddress = (ulong)firstInstruction.Address;
-            ulong lastPermissibleAddress = (ulong)lastInstruction.Address;
-
-            // Create a sorted list of basic blocks for iteration purposes. Only use basic blocks that are valid
-            // (occur at or after the first instruction and start before the last instruction).
-            List<BasicBlock> sortedBasicBlocks = basicBlocks
-                .Where(x => (x.FirstInstructionAddress < lastPermissibleAddress) &&
-                            (x.FirstInstructionAddress >= firstPermissibleAddress))
-                .OrderBy(x => x.FirstInstructionAddress)
-                .ToList();
-
-            // TODO: make sure all previous basic blocks are connected.
-            // TODO: make sure all next basic blocks are connected.
-            // x 1 - Make sure all basic blocks ending with conditional branch instructions have at least two next basic blocks.
-            // o 2 - Make sure all basic blocks ending with return instructions have no basic blocks. This should be automatic.
-            // o 3 - Make sure all basic blocks ending with unconditional branch instructions have only one next basic block.
-
-            // Add each instruction to the basic blocks.
-            int currentBasicBlockIndex = 0;
-            BasicBlock currentBasicBlock = new BasicBlock();
-            BasicBlock nextBasicBlock = new BasicBlock();
-            if (sortedBasicBlocks.Count > 0)
-            {
-                currentBasicBlock = sortedBasicBlocks[currentBasicBlockIndex];
-                Instruction instruction = Instruction.CreateInvalidInstruction();
-                for (int i = 0; i < sortedInstructions.Count; ++i)
-                {
-                    instruction = sortedInstructions[i];
-
-                    if (instruction.Address == 0x00428b07)
-                    {
-                        Console.WriteLine();
-                    }
-
-                    // If the instruction occurs before the current basic block, ignore it.
-                    if (instruction.Address < currentBasicBlock.FirstInstructionAddress)
-                    {
-                        continue;
-                    }
-
-                    // Check to see if another basic block exists.
-                    if (currentBasicBlockIndex + 1 < sortedBasicBlocks.Count)
-                    {
-                        nextBasicBlock = sortedBasicBlocks[currentBasicBlockIndex + 1];
-                        ulong nextBasicBlockAddress = nextBasicBlock.FirstInstructionAddress;
-
-                        // If the current instruction equals the address of the next basic block, then move to that block.
-                        if (nextBasicBlockAddress == instruction.Address)
-                        {
-                            currentBasicBlock = nextBasicBlock;
-                            currentBasicBlockIndex++;
-                        }
-                    }
-
-                    // Check to see if the basic block's instruction list is empty.
-                    if (currentBasicBlock.Instructions.Count == 0)
-                    {
-                        // If the current instruction equals the expected first instruction of the basic block,
-                        // then add the instruction.
-                        if (currentBasicBlock.FirstInstructionAddress == instruction.Address)
-                        {
-                            // Add the instruction to the basic block.
-                            currentBasicBlock.Instructions.Add(instruction);
-                        }
-                        else
-                        {
-                            // Check for decoding errors.
-                            ulong correctFirstInstructionAddress = currentBasicBlock.FirstInstructionAddress;
-                            ulong incorrectFirstInstructionAddress = instruction.Address;
-                            const ulong MAX_NUMBER_OF_BYTES_IN_X86_INSTRUCTION = 15;
-                            ulong addressDifference = incorrectFirstInstructionAddress - correctFirstInstructionAddress;
-
-                            // If the difference in addresses of the correct first instruction and incorrect
-                            // is less than the maximum number of bytes in an x86 instruction, then the error could be
-                            // caused by data within the code segment.
-                            if (addressDifference <= MAX_NUMBER_OF_BYTES_IN_X86_INSTRUCTION)
-                            {
-                                // Calculate the code offset.
-                                int correctOffset = (int)(correctFirstInstructionAddress - codeVirtualBaseAddress);
-
-                                // Copy a portion of the code into a temporary buffer.
-                                byte[] codeSubset = new byte[MAX_NUMBER_OF_BYTES_IN_X86_INSTRUCTION * 2];
-                                Array.Copy(code, correctOffset, codeSubset, 0, (int)MAX_NUMBER_OF_BYTES_IN_X86_INSTRUCTION * 2);
-
-                                // Re-disassemble the bytes to get a correct result.
-                                List<Instruction> reDisassembledInstructions = new List<Instruction>(
-                                    d.DisassembleInstructions(codeSubset, currentBasicBlock.FirstInstructionAddress));
-
-                                foreach (Instruction newInstruction in reDisassembledInstructions)
-                                {
-                                    ulong newInstructionAddress = newInstruction.Address;
-
-                                    if (newInstructionAddress < incorrectFirstInstructionAddress)
-                                    {
-                                        // If this instruction comes before the incorrect instruction, then add it.
-                                        currentBasicBlock.Instructions.Add(newInstruction);
-                                    }
-                                    else if (newInstructionAddress == incorrectFirstInstructionAddress)
-                                    {
-                                        // If this instruction occurs at the address of the incorrect instruction,
-                                        // add the newly disassembled version of the instruction and stop adding
-                                        // more instructions.
-                                        currentBasicBlock.Instructions.Add(newInstruction);
-                                        break;
-                                    }
-                                    else
-                                    {
-                                        throw new Exception("An unknown situation occured while redisassembling some code.");
-                                    }
-                                }
-                            }
-                            else
-                            {
-                                // See if a valid instruction does exist at this address.
-                                Instruction correctInstruction = Instruction.CreateInvalidInstruction();
-
-                                bool foundValidInstruction = false;
-
-                                // Find the correct instruction.
-                                while (!foundValidInstruction)
-                                {
-                                    correctInstruction = sortedInstructions.FirstOrDefault(x => x.Address == currentBasicBlock.FirstInstructionAddress);
-
-                                    if (correctInstruction == null)
-                                    {
-                                        // No instruction exists, so we assume the basic block has been invalidly created.
-                                        if (!basicBlocks.Remove(currentBasicBlock))
-                                        {
-                                            throw new Exception("Could not remove invalid basic block.");
-                                        }
-
-                                        if (currentBasicBlockIndex >= basicBlocks.Count)
-                                        {
-                                            throw new Exception("No more basic blocks exist.");
-                                        }
-
-                                        // Create a new sorted basic block list.
-                                        sortedBasicBlocks = basicBlocks.OrderBy(x => x.FirstInstructionAddress).ToList();
-
-                                        // Set a new current basic block.
-                                        currentBasicBlock = sortedBasicBlocks[currentBasicBlockIndex];
-
-                                        correctInstruction = sortedInstructions.FirstOrDefault(x => (ulong)x.Address == currentBasicBlock.FirstInstructionAddress);
-                                        if (correctInstruction == null)
-                                        {
-                                            continue;
-                                        }
-                                        else
-                                        {
-                                            foundValidInstruction = true;
-                                        }
-                                    }
-                                    else
-                                    {
-                                        // TODO: Handle this error.
-                                        Console.WriteLine("current basic block: 0x" + new IntPtr((long)currentBasicBlock.FirstInstructionAddress).ToString("x"));
-                                        Console.WriteLine("current instruction: " + instruction.AddressAsString);
-                                        Console.WriteLine();
-
-                                        continue;
-                                    }
-                                }
-
-                                // See if previous basic blocks used this instruction and remove the instruction,
-                                // as well as any subsequent instructions, from that basic block.
-                                IEnumerable<BasicBlock> basicBlocksWithCorrectInstruction =
-                                    sortedBasicBlocks.Where(x => x.Instructions.Contains(correctInstruction));
-                                if (basicBlocksWithCorrectInstruction.Count() > 1)
-                                {
-                                    throw new Exception("TODO: handle the case where more than one basic block has the correct instruction.");
-                                }
-
-                                // Only keep the instructions belonging to each basic block containing the
-                                // correct instruction.
-                                foreach (BasicBlock bbToBeCorrected in basicBlocksWithCorrectInstruction)
-                                {
-                                    int indexOfCorrectInstruction = bbToBeCorrected.Instructions.IndexOf(correctInstruction);
-                                    List<Instruction> correctInstructions = bbToBeCorrected.Instructions.Take(indexOfCorrectInstruction).ToList();
-                                    bbToBeCorrected.Instructions.Clear();
-                                    bbToBeCorrected.Instructions.AddRange(correctInstructions);
-                                }
-
-                                // Add the correct instruction to the current basic block.
-                                currentBasicBlock.Instructions.Add(correctInstruction);
-                            }
-                        }
-                    }
-                    else
-                    {
-                        // Add the next basic block.
-                        currentBasicBlock.Instructions.Add(instruction);
-                    }
-
-                    if ((ulong)currentBasicBlock.Instructions.FirstOrDefault().Address != currentBasicBlock.FirstInstructionAddress)
-                    {
-                        Console.WriteLine();
-                    }
-
-                    // If the instruction is a control flow changing instruction, move to the next basic block.
-                    // Do not count call instructions as a flow changing instruction.
-                    if (instruction.FlowType == Instruction.ControlFlow.ConditionalBranch ||
-                        instruction.FlowType == Instruction.ControlFlow.UnconditionalBranch ||
-                        instruction.FlowType == Instruction.ControlFlow.Return)
-                    {
-                        // Check to see if another basic block exists.
-                        if (currentBasicBlockIndex + 1 >= sortedBasicBlocks.Count)
-                        {
-                            // Exit the loop if no more basic blocks remain.
-                            break;
-                        }
-
-                        nextBasicBlock = sortedBasicBlocks[currentBasicBlockIndex + 1];
-
-                        // Link to the fall-through basic block, for when the conditional branch is false.
-                        if (instruction.FlowType == Instruction.ControlFlow.ConditionalBranch)
-                        {
-                            currentBasicBlock.NextBasicBlocks.Add(nextBasicBlock);
-                            nextBasicBlock.PreviousBasicBlocks.Add(currentBasicBlock);
-                        }
-
-                        // Move to the next basic block.
-                        currentBasicBlock = nextBasicBlock;
-                        currentBasicBlockIndex++;
-                    }
-                }
-            }
-
-            basicBlocks = new HashSet<BasicBlock>(sortedBasicBlocks);
-
-            Instruction testInst = instructions.FirstOrDefault(x => x.Address == 0x004c50b2);
-            BasicBlock test = basicBlocks.FirstOrDefault(x => x.FirstInstructionAddress == 0x004c50b2);
-
-            // Link all basic blocks that change control flow because of a conditional or unconditional branch.
-            BasicBlock branchTargetBlock = new BasicBlock();
-            foreach (BasicBlock block in basicBlocks)
-            {
-                lastInstruction = block.Instructions.LastOrDefault();
-
-                if (lastInstruction.FlowType == Instruction.ControlFlow.ConditionalBranch ||
-                    lastInstruction.FlowType == Instruction.ControlFlow.UnconditionalBranch)
-                {
-                    // Find the matching basic block that this basic block can branch to.
-                    branchTargetBlock = basicBlocks.FirstOrDefault(x => x.FirstInstructionAddress.Equals(lastInstruction.BranchTarget));
-
-                    if (branchTargetBlock != null)
-                    {
-                        // Link it with this basic block.
-                        block.NextBasicBlocks.Add(branchTargetBlock);
-                        branchTargetBlock.PreviousBasicBlocks.Add(block);
-                    }
-                    else
-                    {
-                        // Cannot link a non-deterministic branch.
-                    }
-                }
-            }
-
-            // Basic block processing is complete at this point.
-
-            BasicBlock lastBasicBlock = sortedBasicBlocks.LastOrDefault();
-            List<ulong> endAddresses = sortedBasicBlocks.Skip(1).Select(x => x.FirstInstructionAddress).ToList();
-
-            Console.WriteLine();
             */
         }


Ensure the shell provider is disposed in unit test

--- Tests/UnitTests/Foundation.Tests/WindowsShell/ShellObjectCollectionFixture.cs
+++ Tests/UnitTests/Foundation.Tests/WindowsShell/ShellObjectCollectionFixture.cs
@@ -9,11 +9,11 @@
         [TestMethod]
         public void Can_get_mycomputer_nodes()
         {
-            var provider = new ShellProvider();
-
-            var list = provider.MyComputer.Children;
-
-            Assert.IsTrue(list.Count > 0);
+            using (var provider = new ShellProvider())
+            {
+                var list = provider.MyComputer.Children;
+                Assert.IsTrue(list.Count > 0);
+            }
         }
     }
 }


Use a slightly more sane approach when generating the initial kerbals.

--- Client/VesselWorker.cs
+++ Client/VesselWorker.cs
@@ -1259,15 +1259,10 @@

             while (generateKerbals > 0)
             {
-                ProtoCrewMember protoKerbal = CrewGenerator.RandomCrewMemberPrototype(ProtoCrewMember.KerbalType.Crew);
-                if (!HighLogic.CurrentGame.CrewRoster.Exists(protoKerbal.name))
-                {
-                    ProtoCrewMember newKerbal = HighLogic.CurrentGame.CrewRoster.GetNewKerbal(ProtoCrewMember.KerbalType.Crew);
-                    AddCrewMemberToRoster(newKerbal);
-                    serverKerbals[protoKerbal.name] = new ProtoCrewMember(HighLogic.CurrentGame.Mode, protoKerbal);
-                    NetworkWorker.fetch.SendKerbalProtoMessage(protoKerbal);
-                    generateKerbals--;
-                }
+                ProtoCrewMember protoKerbal = HighLogic.CurrentGame.CrewRoster.GetNewKerbal(ProtoCrewMember.KerbalType.Crew);
+                serverKerbals[protoKerbal.name] = new ProtoCrewMember(HighLogic.CurrentGame.Mode, protoKerbal);
+                NetworkWorker.fetch.SendKerbalProtoMessage(protoKerbal);
+                generateKerbals--;
             }
             DarkLog.Debug("Kerbals loaded");
         }


Fix Clear() does not reset trivial fields.

--- src/MsgPack.Rpc/Rpc/Protocols/MessageContext.cs
+++ src/MsgPack.Rpc/Rpc/Protocols/MessageContext.cs
@@ -166,6 +166,9 @@
 			}

 			this._completedSynchronously = false;
+			this.MessageId = null;
+			this._sessionId = 0;
+			this._sessionStartedAt = default( DateTimeOffset );
 		}
 	}
 }


trim 'Type' in property setter

trim 'Type' in property setter

--- src/NHibernate.Test/TypedManyToOne/AddressId.cs
+++ src/NHibernate.Test/TypedManyToOne/AddressId.cs
@@ -2,54 +2,66 @@

 namespace NHibernate.Test.TypedManyToOne
 {
-    [Serializable]
-    public class AddressId
-    {
-        public virtual String Type { get; set; }
-        public virtual String Id { get; set; }
-        private int? requestedHash;
+	[Serializable]
+	public class AddressId
+	{
+		private string _type;
+		private int? requestedHash;

-        public AddressId(String type, String id)
-        {
-            Id = id;
-            Type = type;
-        }
+		public virtual String Type
+		{
+			get { return _type; }
+			set
+			{
+				if (!string.IsNullOrWhiteSpace(value))
+					_type = value.Trim();
+				else
+					_type = value;
+			}
+		}
+		public virtual String Id { get; set; }

-        public AddressId() { }
+		public AddressId(String type, String id)
+		{
+			Id = id;
+			_type = type;
+		}

-        public override bool Equals(object obj)
-        {
-            return Equals(obj as AddressId);
-        }
+		public AddressId() { }

-        public virtual bool Equals(AddressId other)
-        {
-            if (ReferenceEquals(null, other))
-            {
-                return false;
-            }
-            if (ReferenceEquals(this, other))
-            {
-                return true;
-            }
-            return other.Id == Id && Equals(other.Type, Type);
-        }
+		public override bool Equals(object obj)
+		{
+			return Equals(obj as AddressId);
+		}

-        public override int GetHashCode()
-        {
-            if (!requestedHash.HasValue)
-            {
-                unchecked
-                {
-                    requestedHash = (Id.GetHashCode() * 397) ^ Type.GetHashCode();
-                }
-            }
-            return requestedHash.Value;
-        }
+		public virtual bool Equals(AddressId other)
+		{
+			if (ReferenceEquals(null, other))
+			{
+				return false;
+			}
+			if (ReferenceEquals(this, other))
+			{
+				return true;
+			}
+			return other.Id == Id && Equals(other.Type, Type);
+		}

-        public override string ToString()
-        {
-            return Type + '#' + Id;
-        }
-    }
+		public override int GetHashCode()
+		{
+			if (!requestedHash.HasValue)
+			{
+				unchecked
+				{
+					requestedHash = (Id.GetHashCode() * 397) ^ Type.GetHashCode();
+				}
+			}
+			return requestedHash.Value;
+		}
+
+		public override string ToString()
+		{
+			return Type + '#' + Id;
+		}
+	}
 }


Turned on BindByName for ODP to handle parameters correctly.
http://tgaw.wordpress.com/2006/03/03/ora-01722-with-odp-and-command-parameters/

SVN: 488784591515bd4cdaa016be4ec9b172dc4e7caf@5163

--- src/NHibernate/Driver/OracleDataClientDriver.cs
+++ src/NHibernate/Driver/OracleDataClientDriver.cs
@@ -21,6 +21,7 @@
 		private const string connectionTypeName = "Oracle.DataAccess.Client.OracleConnection";
 		private const string commandTypeName = "Oracle.DataAccess.Client.OracleCommand";
 		private static readonly SqlType GuidSqlType = new SqlType(DbType.Binary, 16);
+		private readonly PropertyInfo oracleCommandBindByName;
 		private readonly PropertyInfo oracleDbType;
 		private readonly object oracleDbTypeRefCursor;

@@ -37,6 +38,9 @@
 			connectionTypeName,
 			commandTypeName)
 		{
+			System.Type oracleCommandType = ReflectHelper.TypeFromAssembly("Oracle.DataAccess.Client.OracleCommand", driverAssemblyName, false);
+			oracleCommandBindByName = oracleCommandType.GetProperty("BindByName");
+
 			System.Type parameterType = ReflectHelper.TypeFromAssembly("Oracle.DataAccess.Client.OracleParameter", driverAssemblyName, false);
 			oracleDbType = parameterType.GetProperty("OracleDbType");

@@ -88,6 +92,10 @@
 		{
 			base.OnBeforePrepare(command);

+			// need to explicitly turn on named parameter binding
+			// http://tgaw.wordpress.com/2006/03/03/ora-01722-with-odp-and-command-parameters/
+			oracleCommandBindByName.SetValue(command, true, null);
+
 			CallableParser.Detail detail = CallableParser.Parse(command.CommandText);

 			if (!detail.IsCallable)


Made EndpointAddress virtual

Made EndpointAddress virtual

--- src/NLog/Targets/LogReceiverWebServiceTarget.cs
+++ src/NLog/Targets/LogReceiverWebServiceTarget.cs
@@ -75,7 +75,7 @@
         /// <value>The endpoint address.</value>
         /// <docgen category='Connection Options' order='10' />
         [RequiredParameter]
-        public string EndpointAddress { get; set; }
+        public virtual string EndpointAddress { get; set; }

 #if WCF_SUPPORTED
         /// <summary>
@@ -303,12 +303,12 @@
 #endif
         }

-#if WCF_SUPPORTED
-        /// <summary>
-        /// Creating a new instance of WcfLogReceiverClient
-        ///
-        /// Inheritors can override this method and provide their own
-        /// service configuration - binding and endpoint address
+#if WCF_SUPPORTED
+        /// <summary>
+        /// Creating a new instance of WcfLogReceiverClient
+        ///
+        /// Inheritors can override this method and provide their own
+        /// service configuration - binding and endpoint address
         /// </summary>
         /// <returns></returns>
         protected virtual WcfLogReceiverClient CreateWcfLogReceiverClient()


Fix release-only build issue

Fix release-only build issue

--- src/Package/Impl/Options/R/RToolsOptionsPage.cs
+++ src/Package/Impl/Options/R/RToolsOptionsPage.cs
@@ -177,7 +177,7 @@
 #if DEBUG
         [DefaultValue(LogVerbosity.Traffic)]
 #else
-        [DefaultValue(LogLevel.Normal)]
+        [DefaultValue(LogVerbosity.Normal)]
 #endif
         public LogVerbosity LogLevel {
             get { return RToolsSettings.Current.LogVerbosity; }


AML-3615: remove now redundant extension method.

--- src/SFA.DAS/Hashing/HashingServiceExtensions.cs
+++ src/SFA.DAS/Hashing/HashingServiceExtensions.cs
@@ -1,22 +0,0 @@
-using System;
-using SFA.DAS.HashingService;
-
-namespace SFA.DAS.Hashing
-{
-    public static class HashingServiceExtensions
-    {
-        public static bool TryDecodeValue(this IHashingService hashingService, string input, out long result)
-        {
-            try
-            {
-                result = hashingService.DecodeValue(input);
-                return true;
-            }
-            catch (Exception)
-            {
-                result = default(long);
-                return false;
-            }
-        }
-    }
-}


Fixed bug causing new SignalR not to reconnect

--- src/Servant.Client/SocketClient/SocketClient.cs
+++ src/Servant.Client/SocketClient/SocketClient.cs
@@ -9,6 +9,7 @@
 using Servant.Business.Objects;
 using Servant.Business.Objects.Enums;
 using Servant.Client.Infrastructure;
+using Servant.Client.Service;
 using Servant.Shared;
 using Servant.Shared.SocketClient;
 using TinyIoC;
@@ -29,18 +30,8 @@
             Connect();
         }

-        private static void Connect()
+        private static void InitializeConnection()
         {
-            if (_connection != null)
-            {
-                _connection.Dispose();
-            }
-
-            if (string.IsNullOrWhiteSpace(Configuration.ServantIoKey))
-            {
-                MessageHandler.Print("Cannot connect without a key.");
-                return;
-            }
             _connection = new HubConnection(Configuration.ServantIoHost,
                 new Dictionary<string, string>()
                 {
@@ -48,28 +39,9 @@
                     {"organizationGuid", Configuration.ServantIoKey},
                     {"servername", Environment.MachineName},
                     {"version", Configuration.Version.ToString()},
-                }) {TransportConnectTimeout = TimeSpan.FromSeconds(10)};
+                });
+
             _myHub = _connection.CreateHubProxy("ServantClientHub");
-
-            while (_connection.State != ConnectionState.Connected)
-            {
-                if (_connection.State == ConnectionState.Connecting)
-                {
-                    Thread.Sleep(2000);
-                }
-                else
-                {
-                    MessageHandler.Print(string.Format("Trying to connect to {0}...", Configuration.ServantIoHost));
-                    try
-                    {
-                        _connection.Start().Wait();
-                    }
-                    catch (Exception)
-                    {
-                        Thread.Sleep(2000);
-                    }
-                }
-            }

             _myHub.On<CommandRequest>("Request", request =>
             {
@@ -202,36 +174,46 @@
                 }
             });

-            _connection.Closed += () =>
-            {
-                MessageHandler.Print(string.Format("Connection to {0} closed.", Configuration.ServantIoHost));
-                Connect();
+            _connection.StateChanged += change =>
+            {
+                MessageHandler.Print("State changed to: " + change.NewState);
+                if (change.NewState == ConnectionState.Disconnected)
+                {
+                    Connect();
+                }
             };

-            _connection.Reconnecting += () => MessageHandler.Print(string.Format("Lost connection to {0}. Reconnecting...", Configuration.ServantIoHost));
-
             _connection.Error += exception =>
             {
                 MessageHandler.LogException(exception.Message + Environment.NewLine + exception.StackTrace);

                 try
                 {
-                    var exceptionUrl = Configuration.ServantIoHost + "/exceptions/log";
-                    new WebClient().UploadValues(exceptionUrl, new NameValueCollection()
-                    {
-                        {"InstallationGuid", Configuration.InstallationGuid.ToString()},
-                        {"Message", exception.Message},
-                        {"Stacktrace", exception.StackTrace}
-                    });
+                    var exceptionUrl = new System.Uri(Configuration.ServantIoHost + "/exceptions/log");
+                    new WebClient().UploadValuesAsync(exceptionUrl, new NameValueCollection()
+                                                                                {
+                                                                                { "InstallationGuid", Configuration.InstallationGuid.ToString() },
+                                                                                { "Message", exception.Message},
+                                                                                { "Stacktrace", exception.StackTrace }
+                                                                                });
                 }
                 catch (Exception)
                 {
                 }
-
-                Connect();
             };
-
-            MessageHandler.Print(string.Format("Successfully connected to {0}", Configuration.ServantIoHost));
+        }
+
+        private static void Connect()
+        {
+            if (string.IsNullOrWhiteSpace(Configuration.ServantIoKey))
+            {
+                MessageHandler.Print("Cannot connect without a key.");
+                return;
+            }
+
+            MessageHandler.Print("Connecting...");
+            InitializeConnection();
+            _connection.Start().Wait(TimeSpan.FromSeconds(5));
         }
     }
 }


- Investigation: #296 (resp file support)

--- src/Tests.CSScriptLib/Evaluator.CodeDom.Test.cs
+++ src/Tests.CSScriptLib/Evaluator.CodeDom.Test.cs
@@ -24,7 +24,7 @@
             };

             Assembly asm = CSScript.CodeDomEvaluator.CompileCode(
-                    @"using System;
+                     @"using System;
                       public class Script
                       {
                           public int Sum(int a, int b)
@@ -36,7 +36,7 @@
                               #endif
                           }
                       }",
-                      info);
+                     info);

             dynamic script = asm.CreateObject("*");
             var result = script.Sum(7, 3);
@@ -149,6 +149,28 @@
             finally
             {
                 info.AssemblyFile.FileDelete(rethrow: false); // assembly is locked so only showing the intention
+            }
+        }
+
+        [Fact]
+        public void use_resp_file()
+        {
+            var respFile = $"{nameof(use_resp_file)}.resp".GetFullPath();
+            File.WriteAllText(respFile, "/r:Foo.dll");
+
+            CSScript.EvaluatorConfig.CompilerOptions = $"\"@{respFile}\"";
+
+            try
+            {
+                dynamic script = CSScript.CodeDomEvaluator
+                                         .LoadMethod(@"public (int, int) func()
+                                                   {
+                                                       return (0,5);
+                                                   }");
+            }
+            catch (CompilerException e)
+            {
+                Assert.Contains("Metadata file 'Foo.dll' could not be found", e.Message);
             }
         }

@@ -212,7 +234,7 @@
             var script_calc = "calc.cs".GetFullPath();

             File.WriteAllText(script_math,
-                            @"using System;
+                              @"using System;

                               public class math
                               {
@@ -220,7 +242,7 @@
                               }");

             File.WriteAllText(script_calc,
-                            $@"//css_inc {script_math}
+                              $@"//css_inc {script_math}
                                using System;

                                public class Calc


Fixes: U4-2730 500 - PostSave

Fixes: U4-2730 500 - PostSave

--- src/Umbraco.Core/PropertyEditors/ValueEditor.cs
+++ src/Umbraco.Core/PropertyEditors/ValueEditor.cs
@@ -139,7 +139,9 @@
                     break;
                 case DataTypeDatabaseType.Integer:
                     //ensure these are nullable so we can return a null if required
-                    valueType = typeof(int?);
+                    //NOTE: This is allowing type of 'long' because I think json.net will deserialize a numerical value as long
+                    // instead of int. Even though our db will not support this (will get truncated), we'll at least parse to this.
+                    valueType = typeof(long?);
                     break;
                 case DataTypeDatabaseType.Date:
                     //ensure these are nullable so we can return a null if required


9642.2: fix missing path

9642.2: fix missing path

--- a_mini/projects/Tests/Test_BasicPixelFarm/Program.cs
+++ a_mini/projects/Tests/Test_BasicPixelFarm/Program.cs
@@ -18,15 +18,13 @@
             //temp
             //TODO: fix this ,
             //set data dir before load
-            Typography.TextBreak.CustomBreakerBuilder.DataDir = @"../../Deps_I18N/LayoutFarm.TextBreak/icu58/brkitr_src/dictionaries";
+            Typography.TextBreak.CustomBreakerBuilder.DataDir = @"../../PixelFarm/Typography/Typography.TextBreak/icu58/brkitr_src/dictionaries";

             LayoutFarm.Composers.Default.TextBreaker = new LayoutFarm.Composers.MyManagedTextBreaker();
             //RootDemoPath.Path = @"..\Data";
             //you can use your font loader
             PixelFarm.Drawing.WinGdi.WinGdiPlusPlatform.SetFontLoader(YourImplementation.BootStrapWinGdi.myFontLoader);
             PixelFarm.Drawing.GLES2.GLES2Platform.SetFontLoader(YourImplementation.BootStrapOpenGLES2.myFontLoader);
-
-
             ////-------------------------------
             formDemoList = new LayoutFarm.Dev.FormDemoList();
             formDemoList.LoadDemoList(typeof(Program));


Rename StringValues to Strings in tests

Rename StringValues to Strings in tests

--- tests/StringsTests.cs
+++ tests/StringsTests.cs
@@ -8,7 +8,7 @@
 using System.Linq;
 using NUnit.Framework;
 using NAssert = NUnit.Framework.Assert;
-using StringValues = WebLinq.Collections.Strings;
+using WebLinq.Collections;

 namespace WebLinq.Tests
 {
@@ -21,41 +21,41 @@

     public class StringsTests
     {
-        public static IEnumerable<StringValues> DefaultOrNullStringValues
+        public static IEnumerable<Strings> DefaultOrNullStrings
         {
             get
             {
-                return new StringValues[]
+                return new Strings[]
                 {
-                    new StringValues(),
-                    new StringValues(default(ImmutableArray<string>)),
+                    new Strings(),
+                    new Strings(default(ImmutableArray<string>)),
                 };
             }
         }

-        public static IEnumerable<StringValues> EmptyStringValues
+        public static IEnumerable<Strings> EmptyStrings
         {
             get
             {
-                return new StringValues[]
+                return new Strings[]
                 {
-                    StringValues.Empty,
-                    new StringValues(ImmutableArray<string>.Empty),
+                    Strings.Empty,
+                    new Strings(ImmutableArray<string>.Empty),
                     ImmutableArray<string>.Empty
                 };
             }
         }

-        public static IEnumerable<StringValues> FilledStringValues
+        public static IEnumerable<Strings> FilledStrings
         {
             get
             {
-                return new StringValues[]
+                return new Strings[]
                 {
-                    new StringValues("abc"),
-                    new StringValues(ImmutableArray.Create("abc")),
-                    new StringValues(ImmutableArray.Create("abc", "bcd")),
-                    new StringValues(ImmutableArray.Create("abc", "bcd", "foo")),
+                    new Strings("abc"),
+                    new Strings(ImmutableArray.Create("abc")),
+                    new Strings(ImmutableArray.Create("abc", "bcd")),
+                    new Strings(ImmutableArray.Create("abc", "bcd", "foo")),
                     "abc",
                     ImmutableArray.Create("abc"),
                     ImmutableArray.Create("abc", "bcd"),
@@ -64,51 +64,51 @@
             }
         }

-        public static IEnumerable FilledStringValuesWithExpectedStrings
+        public static IEnumerable FilledStringsWithExpectedStrings
         {
             get
             {
                 var args = new[]
                 {
-                    (new StringValues(string.Empty), string.Empty ),
-                    (new StringValues(ImmutableArray.Create(string.Empty)), string.Empty ),
-                    (new StringValues("abc"), "abc"),
+                    (new Strings(string.Empty), string.Empty ),
+                    (new Strings(ImmutableArray.Create(string.Empty)), string.Empty ),
+                    (new Strings("abc"), "abc"),
                 };
                 return from a in args select new object[] { a.Item1, a.Item2 };
             }
         }

-        public static IEnumerable FilledStringValuesWithExpectedObjects
+        public static IEnumerable FilledStringsWithExpectedObjects
         {
             get
             {
                 var args = new[]
                 {
-                    (default(StringValues), (object)null),
-                    (StringValues.Empty, (object)null),
-                    (new StringValues(ImmutableArray<string>.Empty), (object)null),
-                    (new StringValues("abc"), (object)"abc"),
-                    (new StringValues("abc"), (object)new[] { "abc" }),
-                    (new StringValues(ImmutableArray.Create("abc")), (object)new[] { "abc" }),
-                    (new StringValues(ImmutableArray.Create("abc", "bcd")), (object)new[] { "abc", "bcd" }),
+                    (default(Strings), (object)null),
+                    (Strings.Empty, (object)null),
+                    (new Strings(ImmutableArray<string>.Empty), (object)null),
+                    (new Strings("abc"), (object)"abc"),
+                    (new Strings("abc"), (object)new[] { "abc" }),
+                    (new Strings(ImmutableArray.Create("abc")), (object)new[] { "abc" }),
+                    (new Strings(ImmutableArray.Create("abc", "bcd")), (object)new[] { "abc", "bcd" }),
                 };
                 return from a in args select new[] { a.Item1, a.Item2 };
             }
         }

-        public static IEnumerable FilledStringValuesWithExpected
+        public static IEnumerable FilledStringsWithExpected
         {
             get
             {
-                var args = new(StringValues, string[])[]
+                var args = new(Strings, string[])[]
                 {
-                    (default(StringValues), new string[0]),
-                    (StringValues.Empty, new string[0]),
-                    (new StringValues(string.Empty), new[] { string.Empty }),
-                    (new StringValues("abc"), new[] { "abc" }),
-                    (new StringValues(ImmutableArray.Create("abc")), new[] { "abc" }),
-                    (new StringValues(ImmutableArray.Create("abc", "bcd")), new[] { "abc", "bcd" }),
-                    (new StringValues(ImmutableArray.Create("abc", "bcd", "foo")), new[] { "abc", "bcd", "foo" }),
+                    (default(Strings), new string[0]),
+                    (Strings.Empty, new string[0]),
+                    (new Strings(string.Empty), new[] { string.Empty }),
+                    (new Strings("abc"), new[] { "abc" }),
+                    (new Strings(ImmutableArray.Create("abc")), new[] { "abc" }),
+                    (new Strings(ImmutableArray.Create("abc", "bcd")), new[] { "abc", "bcd" }),
+                    (new Strings(ImmutableArray.Create("abc", "bcd", "foo")), new[] { "abc", "bcd", "foo" }),
                     (string.Empty, new[] { string.Empty }),
                     ("abc", new[] { "abc" }),
                     (ImmutableArray.Create("abc"), new[] { "abc" }),
@@ -120,101 +120,101 @@
         }

         [Theory]
-        [TestCaseSource(nameof(DefaultOrNullStringValues))]
-        [TestCaseSource(nameof(EmptyStringValues))]
-        [TestCaseSource(nameof(FilledStringValues))]
-        public void IsReadOnly_True(StringValues stringValues)
-        {
-            Assert.True(((IList<string>)stringValues).IsReadOnly);
-            Assert.Throws<NotSupportedException>(() => ((IList<string>)stringValues)[0] = string.Empty);
-            Assert.Throws<NotSupportedException>(() => ((ICollection<string>)stringValues).Add(string.Empty));
-            Assert.Throws<NotSupportedException>(() => ((IList<string>)stringValues).Insert(0, string.Empty));
-            Assert.Throws<NotSupportedException>(() => ((ICollection<string>)stringValues).Remove(string.Empty));
-            Assert.Throws<NotSupportedException>(() => ((IList<string>)stringValues).RemoveAt(0));
-            Assert.Throws<NotSupportedException>(() => ((ICollection<string>)stringValues).Clear());
-        }
-
-        [Theory]
-        [TestCaseSource(nameof(DefaultOrNullStringValues))]
-        public void DefaultOrNull_ExpectedValues(StringValues stringValues)
-        {
-            Assert.Empty((string[])stringValues);
-        }
-
-        [Theory]
-        [TestCaseSource(nameof(DefaultOrNullStringValues))]
-        [TestCaseSource(nameof(EmptyStringValues))]
-        public void DefaultNullOrEmpty_ExpectedValues(StringValues stringValues)
-        {
-            Assert.Empty(stringValues);
-            Assert.Null((string)stringValues);
-            Assert.Equal((string)null, stringValues);
-            Assert.Equal(string.Empty, stringValues.ToString());
-            Assert.Equal(new string[0], stringValues.ToArray());
-
-            Assert.True(StringValues.IsNullOrEmpty(stringValues));
-            Assert.Throws<IndexOutOfRangeException>(() => _ = stringValues[0]);
-            Assert.Throws<IndexOutOfRangeException>(() => _ = ((IList<string>)stringValues)[0]);
-            Assert.Equal(string.Empty, stringValues.ToString());
-            Assert.Equal(-1, ((IList<string>)stringValues).IndexOf(null));
-            Assert.Equal(-1, ((IList<string>)stringValues).IndexOf(string.Empty));
-            Assert.Equal(-1, ((IList<string>)stringValues).IndexOf("not there"));
-            Assert.False(((ICollection<string>)stringValues).Contains(null));
-            Assert.False(((ICollection<string>)stringValues).Contains(string.Empty));
-            Assert.False(((ICollection<string>)stringValues).Contains("not there"));
-            Assert.Empty(stringValues);
+        [TestCaseSource(nameof(DefaultOrNullStrings))]
+        [TestCaseSource(nameof(EmptyStrings))]
+        [TestCaseSource(nameof(FilledStrings))]
+        public void IsReadOnly_True(Strings strings)
+        {
+            Assert.True(((IList<string>)strings).IsReadOnly);
+            Assert.Throws<NotSupportedException>(() => ((IList<string>)strings)[0] = string.Empty);
+            Assert.Throws<NotSupportedException>(() => ((ICollection<string>)strings).Add(string.Empty));
+            Assert.Throws<NotSupportedException>(() => ((IList<string>)strings).Insert(0, string.Empty));
+            Assert.Throws<NotSupportedException>(() => ((ICollection<string>)strings).Remove(string.Empty));
+            Assert.Throws<NotSupportedException>(() => ((IList<string>)strings).RemoveAt(0));
+            Assert.Throws<NotSupportedException>(() => ((ICollection<string>)strings).Clear());
+        }
+
+        [Theory]
+        [TestCaseSource(nameof(DefaultOrNullStrings))]
+        public void DefaultOrNull_ExpectedValues(Strings strings)
+        {
+            Assert.Empty((string[])strings);
+        }
+
+        [Theory]
+        [TestCaseSource(nameof(DefaultOrNullStrings))]
+        [TestCaseSource(nameof(EmptyStrings))]
+        public void DefaultNullOrEmpty_ExpectedValues(Strings strings)
+        {
+            Assert.Empty(strings);
+            Assert.Null((string)strings);
+            Assert.Equal((string)null, strings);
+            Assert.Equal(string.Empty, strings.ToString());
+            Assert.Equal(new string[0], strings.ToArray());
+
+            Assert.True(Strings.IsNullOrEmpty(strings));
+            Assert.Throws<IndexOutOfRangeException>(() => _ = strings[0]);
+            Assert.Throws<IndexOutOfRangeException>(() => _ = ((IList<string>)strings)[0]);
+            Assert.Equal(string.Empty, strings.ToString());
+            Assert.Equal(-1, ((IList<string>)strings).IndexOf(null));
+            Assert.Equal(-1, ((IList<string>)strings).IndexOf(string.Empty));
+            Assert.Equal(-1, ((IList<string>)strings).IndexOf("not there"));
+            Assert.False(((ICollection<string>)strings).Contains(null));
+            Assert.False(((ICollection<string>)strings).Contains(string.Empty));
+            Assert.False(((ICollection<string>)strings).Contains("not there"));
+            Assert.Empty(strings);
         }

         [Test]
         public void ImplicitStringConverter_Works()
         {
             string nullString = null;
-            StringValues stringValues = nullString;
-            Assert.Null((string)stringValues);
-            Assert.Equal(new string[] { null }, (string[])stringValues);
+            Strings strings = nullString;
+            Assert.Null((string)strings);
+            Assert.Equal(new string[] { null }, (string[])strings);

             string aString = "abc";
-            stringValues = aString;
-            Assert.Single(stringValues);
-            Assert.Equal(aString, stringValues);
-            Assert.Equal(aString, stringValues[0]);
-            Assert.Equal(aString, ((IList<string>)stringValues)[0]);
-            Assert.Equal<string[]>(new string[] { aString }, stringValues);
+            strings = aString;
+            Assert.Single(strings);
+            Assert.Equal(aString, strings);
+            Assert.Equal(aString, strings[0]);
+            Assert.Equal(aString, ((IList<string>)strings)[0]);
+            Assert.Equal<string[]>(new string[] { aString }, strings);
         }

         [Test]
         public void ImplicitStringArrayConverter_Works()
         {
             ImmutableArray<string> nullStringArray = default;
-            StringValues stringValues = nullStringArray;
-            Assert.Empty(stringValues);
-            Assert.Null((string)stringValues);
-            Assert.Empty((string[])stringValues);
+            Strings strings = nullStringArray;
+            Assert.Empty(strings);
+            Assert.Null((string)strings);
+            Assert.Empty((string[])strings);

             string aString = "abc";
             var aStringArray = ImmutableArray.Create(aString);
-            stringValues = aStringArray;
-            Assert.Single(stringValues);
-            Assert.Equal(aString, stringValues);
-            Assert.Equal(aString, stringValues[0]);
-            Assert.Equal(aString, ((IList<string>)stringValues)[0]);
-            Assert.Equal(aStringArray, stringValues);
+            strings = aStringArray;
+            Assert.Single(strings);
+            Assert.Equal(aString, strings);
+            Assert.Equal(aString, strings[0]);
+            Assert.Equal(aString, ((IList<string>)strings)[0]);
+            Assert.Equal(aStringArray, strings);

             aString = "abc";
             string bString = "bcd";
             aStringArray = ImmutableArray.Create(aString, bString);
-            stringValues = aStringArray;
-            Assert.Equal(2, stringValues.Count);
-            Assert.Equal("abc,bcd", stringValues);
-            Assert.Equal(aStringArray, stringValues);
-        }
-
-        [Theory]
-        [TestCaseSource(nameof(DefaultOrNullStringValues))]
-        [TestCaseSource(nameof(EmptyStringValues))]
-        public void DefaultNullOrEmpty_Enumerator(StringValues stringValues)
-        {
-            var e = stringValues.GetEnumerator();
+            strings = aStringArray;
+            Assert.Equal(2, strings.Count);
+            Assert.Equal("abc,bcd", strings);
+            Assert.Equal(aStringArray, strings);
+        }
+
+        [Theory]
+        [TestCaseSource(nameof(DefaultOrNullStrings))]
+        [TestCaseSource(nameof(EmptyStrings))]
+        public void DefaultNullOrEmpty_Enumerator(Strings strings)
+        {
+            var e = strings.GetEnumerator();
             Assert.Null(e.Current);
             Assert.False(e.MoveNext());
             Assert.Null(e.Current);
@@ -222,7 +222,7 @@
             Assert.False(e.MoveNext());
             Assert.False(e.MoveNext());

-            var e1 = ((IEnumerable<string>)stringValues).GetEnumerator();
+            var e1 = ((IEnumerable<string>)strings).GetEnumerator();
             Assert.Null(e1.Current);
             Assert.False(e1.MoveNext());
             Assert.Null(e1.Current);
@@ -230,7 +230,7 @@
             Assert.False(e1.MoveNext());
             Assert.False(e1.MoveNext());

-            var e2 = ((IEnumerable)stringValues).GetEnumerator();
+            var e2 = ((IEnumerable)strings).GetEnumerator();
             Assert.Null(e2.Current);
             Assert.False(e2.MoveNext());
             Assert.Null(e2.Current);
@@ -240,10 +240,10 @@
         }

         [Theory]
-        [TestCaseSource(nameof(FilledStringValuesWithExpected))]
-        public void Enumerator(StringValues stringValues, string[] expected)
-        {
-            var e = stringValues.GetEnumerator();
+        [TestCaseSource(nameof(FilledStringsWithExpected))]
+        public void Enumerator(Strings strings, string[] expected)
+        {
+            var e = strings.GetEnumerator();
             for (int i = 0; i < expected.Length; i++)
             {
                 Assert.True(e.MoveNext());
@@ -253,7 +253,7 @@
             Assert.False(e.MoveNext());
             Assert.False(e.MoveNext());

-            var e1 = ((IEnumerable<string>)stringValues).GetEnumerator();
+            var e1 = ((IEnumerable<string>)strings).GetEnumerator();
             for (int i = 0; i < expected.Length; i++)
             {
                 Assert.True(e1.MoveNext());
@@ -263,7 +263,7 @@
             Assert.False(e1.MoveNext());
             Assert.False(e1.MoveNext());

-            var e2 = ((IEnumerable)stringValues).GetEnumerator();
+            var e2 = ((IEnumerable)strings).GetEnumerator();
             for (int i = 0; i < expected.Length; i++)
             {
                 Assert.True(e2.MoveNext());
@@ -275,10 +275,10 @@
         }

         [Theory]
-        [TestCaseSource(nameof(FilledStringValuesWithExpected))]
-        public void IndexOf(StringValues stringValues, string[] expected)
-        {
-            IList<string> list = stringValues;
+        [TestCaseSource(nameof(FilledStringsWithExpected))]
+        public void IndexOf(Strings strings, string[] expected)
+        {
+            IList<string> list = strings;
             Assert.Equal(-1, list.IndexOf("not there"));
             for (int i = 0; i < expected.Length; i++)
             {
@@ -287,10 +287,10 @@
         }

         [Theory]
-        [TestCaseSource(nameof(FilledStringValuesWithExpected))]
-        public void Contains(StringValues stringValues, string[] expected)
-        {
-            ICollection<string> collection = stringValues;
+        [TestCaseSource(nameof(FilledStringsWithExpected))]
+        public void Contains(Strings strings, string[] expected)
+        {
+            ICollection<string> collection = strings;
             Assert.False(collection.Contains("not there"));
             for (int i = 0; i < expected.Length; i++)
             {
@@ -299,12 +299,12 @@
         }

         [Theory]
-        [TestCaseSource(nameof(DefaultOrNullStringValues))]
-        [TestCaseSource(nameof(EmptyStringValues))]
-        [TestCaseSource(nameof(FilledStringValues))]
-        public void CopyTo_TooSmall(StringValues stringValues)
-        {
-            ICollection<string> collection = stringValues;
+        [TestCaseSource(nameof(DefaultOrNullStrings))]
+        [TestCaseSource(nameof(EmptyStrings))]
+        [TestCaseSource(nameof(FilledStrings))]
+        public void CopyTo_TooSmall(Strings strings)
+        {
+            ICollection<string> collection = strings;
             string[] tooSmall = new string[0];

             if (collection.Count > 0)
@@ -314,10 +314,10 @@
         }

         [Theory]
-        [TestCaseSource(nameof(FilledStringValuesWithExpected))]
-        public void CopyTo_CorrectSize(StringValues stringValues, string[] expected)
-        {
-            ICollection<string> collection = stringValues;
+        [TestCaseSource(nameof(FilledStringsWithExpected))]
+        public void CopyTo_CorrectSize(Strings strings, string[] expected)
+        {
+            ICollection<string> collection = strings;
             string[] actual = new string[expected.Length];

             if (collection.Count > 0)
@@ -330,57 +330,57 @@
         }

         [Theory]
-        [TestCaseSource(nameof(DefaultOrNullStringValues))]
-        [TestCaseSource(nameof(EmptyStringValues))]
-        public void DefaultNullOrEmpty_Concat(StringValues stringValues)
+        [TestCaseSource(nameof(DefaultOrNullStrings))]
+        [TestCaseSource(nameof(EmptyStrings))]
+        public void DefaultNullOrEmpty_Concat(Strings strings)
         {
             var expected = ImmutableArray.Create("abc", "bcd", "foo");
-            StringValues expectedStringValues = new StringValues(expected);
-            Assert.Equal(expected, StringValues.Concat(stringValues, expectedStringValues));
-            Assert.Equal(expected, StringValues.Concat(expectedStringValues, stringValues));
-
-
-            Assert.Equal(new StringValues(ImmutableArray.Create((string) null).AddRange(expected)),
-                         StringValues.Concat((string)null, in expectedStringValues));
-
-            Assert.Equal(new StringValues(expected.Add(null)),
-                         StringValues.Concat(in expectedStringValues, (string)null));
+            Strings expectedStrings = new Strings(expected);
+            Assert.Equal(expected, Strings.Concat(strings, expectedStrings));
+            Assert.Equal(expected, Strings.Concat(expectedStrings, strings));
+
+
+            Assert.Equal(new Strings(ImmutableArray.Create((string) null).AddRange(expected)),
+                         Strings.Concat((string)null, in expectedStrings));
+
+            Assert.Equal(new Strings(expected.Add(null)),
+                         Strings.Concat(in expectedStrings, (string)null));

             string[] empty = new string[0];
-            StringValues emptyStringValues = new StringValues(ImmutableArray<string>.Empty);
-            Assert.Equal(empty, StringValues.Concat(stringValues, StringValues.Empty));
-            Assert.Equal(empty, StringValues.Concat(StringValues.Empty, stringValues));
-            Assert.Equal(empty, StringValues.Concat(stringValues, new StringValues()));
-            Assert.Equal(empty, StringValues.Concat(new StringValues(), stringValues));
+            Strings emptyStrings = new Strings(ImmutableArray<string>.Empty);
+            Assert.Equal(empty, Strings.Concat(strings, Strings.Empty));
+            Assert.Equal(empty, Strings.Concat(Strings.Empty, strings));
+            Assert.Equal(empty, Strings.Concat(strings, new Strings()));
+            Assert.Equal(empty, Strings.Concat(new Strings(), strings));

             string[] @null = { null };
-            Assert.Equal(@null, StringValues.Concat((string)null, in emptyStringValues));
-            Assert.Equal(@null, StringValues.Concat(in emptyStringValues, (string)null));
-        }
-
-        [Theory]
-        [TestCaseSource(nameof(FilledStringValuesWithExpected))]
-        public void Concat(StringValues stringValues, string[] array)
+            Assert.Equal(@null, Strings.Concat((string)null, in emptyStrings));
+            Assert.Equal(@null, Strings.Concat(in emptyStrings, (string)null));
+        }
+
+        [Theory]
+        [TestCaseSource(nameof(FilledStringsWithExpected))]
+        public void Concat(Strings strings, string[] array)
         {
             var filled = ImmutableArray.Create("abc", "bcd", "foo");

             string[] expectedPrepended = array.Concat(filled).ToArray();
-            Assert.Equal(expectedPrepended, StringValues.Concat(stringValues, new StringValues(filled)));
+            Assert.Equal(expectedPrepended, Strings.Concat(strings, new Strings(filled)));

             string[] expectedAppended = filled.Concat(array).ToArray();
-            Assert.Equal(expectedAppended, StringValues.Concat(new StringValues(filled), stringValues));
-
-            StringValues values = stringValues;
+            Assert.Equal(expectedAppended, Strings.Concat(new Strings(filled), strings));
+
+            Strings values = strings;
             foreach (string s in filled)
             {
-                values = StringValues.Concat(in values, s);
+                values = Strings.Concat(in values, s);
             }
             Assert.Equal(expectedPrepended, values);

-            values = stringValues;
+            values = strings;
             foreach (string s in filled.Reverse())
             {
-                values = StringValues.Concat(s, in values);
+                values = Strings.Concat(s, in values);
             }
             Assert.Equal(expectedAppended, values);
         }
@@ -391,25 +391,25 @@
             var equalString = "abc";

             var equalStringArray = new string[] { equalString };
-            var equalStringValues = new StringValues(equalString);
-            var otherStringValues = new StringValues(equalString);
+            var equalStrings = new Strings(equalString);
+            var otherStrings = new Strings(equalString);
             var stringArray = ImmutableArray.Create(equalString, equalString);
-            var stringValuesArray = new StringValues(stringArray);
-
-            Assert.True(equalStringValues == otherStringValues);
-
-            Assert.True(equalStringValues == equalString);
-            Assert.True(equalString == equalStringValues);
-
-            Assert.True(equalStringValues == equalStringArray);
-            Assert.True(equalStringArray == equalStringValues);
+            var stringValuesArray = new Strings(stringArray);
+
+            Assert.True(equalStrings == otherStrings);
+
+            Assert.True(equalStrings == equalString);
+            Assert.True(equalString == equalStrings);
+
+            Assert.True(equalStrings == equalStringArray);
+            Assert.True(equalStringArray == equalStrings);

             Assert.True(stringArray == stringValuesArray);
             Assert.True(stringValuesArray == stringArray);

             Assert.False(stringValuesArray == equalString);
             Assert.False(stringValuesArray == equalStringArray);
-            Assert.False(stringValuesArray == equalStringValues);
+            Assert.False(stringValuesArray == equalStrings);
         }

         [Test]
@@ -418,25 +418,25 @@
             var equalString = "abc";

             var equalStringArray = new string[] { equalString };
-            var equalStringValues = new StringValues(equalString);
-            var otherStringValues = new StringValues(equalString);
+            var equalStrings = new Strings(equalString);
+            var otherStrings = new Strings(equalString);
             var stringArray = ImmutableArray.Create(equalString, equalString);
-            var stringValuesArray = new StringValues(stringArray);
-
-            Assert.False(equalStringValues != otherStringValues);
-
-            Assert.False(equalStringValues != equalString);
-            Assert.False(equalString != equalStringValues);
-
-            Assert.False(equalStringValues != equalStringArray);
-            Assert.False(equalStringArray != equalStringValues);
+            var stringValuesArray = new Strings(stringArray);
+
+            Assert.False(equalStrings != otherStrings);
+
+            Assert.False(equalStrings != equalString);
+            Assert.False(equalString != equalStrings);
+
+            Assert.False(equalStrings != equalStringArray);
+            Assert.False(equalStringArray != equalStrings);

             Assert.False(stringArray != stringValuesArray);
             Assert.False(stringValuesArray != stringArray);

             Assert.True(stringValuesArray != equalString);
             Assert.True(stringValuesArray != equalStringArray);
-            Assert.True(stringValuesArray != equalStringValues);
+            Assert.True(stringValuesArray != equalStrings);
         }

         [Test]
@@ -445,56 +445,56 @@
             var equalString = "abc";

             var equalStringArray = new string[] { equalString };
-            var equalStringValues = new StringValues(equalString);
+            var equalStrings = new Strings(equalString);
             var stringArray = ImmutableArray.Create(equalString, equalString);
-            var stringValuesArray = new StringValues(stringArray);
-
-            Assert.True(equalStringValues.Equals(equalStringValues));
-            Assert.True(equalStringValues.Equals(equalString));
-            Assert.True(equalStringValues.Equals(equalStringArray));
+            var stringValuesArray = new Strings(stringArray);
+
+            Assert.True(equalStrings.Equals(equalStrings));
+            Assert.True(equalStrings.Equals(equalString));
+            Assert.True(equalStrings.Equals(equalStringArray));
             Assert.True(stringValuesArray.Equals(stringArray));
         }

         [Theory]
-        [TestCaseSource(nameof(FilledStringValuesWithExpectedObjects))]
-        public void Equals_ObjectEquals(StringValues stringValues, object obj)
-        {
-            Assert.True(stringValues == obj);
-            Assert.True(obj == stringValues);
-        }
-
-        [Theory]
-        [TestCaseSource(nameof(FilledStringValuesWithExpectedObjects))]
-        public void Equals_ObjectNotEquals(StringValues stringValues, object obj)
-        {
-            Assert.False(stringValues != obj);
-            Assert.False(obj != stringValues);
-        }
-
-        [Theory]
-        [TestCaseSource(nameof(FilledStringValuesWithExpectedStrings))]
-        public void Equals_String(StringValues stringValues, string expected)
-        {
-            var notEqual = new StringValues("bcd");
-
-            Assert.True(StringValues.Equals(stringValues, expected));
-            Assert.False(StringValues.Equals(stringValues, notEqual));
-        }
-
-        [Theory]
-        [TestCaseSource(nameof(FilledStringValuesWithExpected))]
-        public void Equals_StringArray(StringValues stringValues, string[] expected)
+        [TestCaseSource(nameof(FilledStringsWithExpectedObjects))]
+        public void Equals_ObjectEquals(Strings strings, object obj)
+        {
+            Assert.True(strings == obj);
+            Assert.True(obj == strings);
+        }
+
+        [Theory]
+        [TestCaseSource(nameof(FilledStringsWithExpectedObjects))]
+        public void Equals_ObjectNotEquals(Strings strings, object obj)
+        {
+            Assert.False(strings != obj);
+            Assert.False(obj != strings);
+        }
+
+        [Theory]
+        [TestCaseSource(nameof(FilledStringsWithExpectedStrings))]
+        public void Equals_String(Strings strings, string expected)
+        {
+            var notEqual = new Strings("bcd");
+
+            Assert.True(Strings.Equals(strings, expected));
+            Assert.False(Strings.Equals(strings, notEqual));
+        }
+
+        [Theory]
+        [TestCaseSource(nameof(FilledStringsWithExpected))]
+        public void Equals_StringArray(Strings strings, string[] expected)
         {
             var notEqual = ImmutableArray.Create("bcd", "abc");

-            Assert.True(StringValues.Equals(stringValues, expected));
-            Assert.False(StringValues.Equals(stringValues, notEqual));
+            Assert.True(Strings.Equals(strings, expected));
+            Assert.False(Strings.Equals(strings, notEqual));
         }

         [Test]
         public void NullString()
         {
-            var strings = new StringValues((string)null);
+            var strings = new Strings((string)null);

             NAssert.AreEqual(1, strings.Count);
             NAssert.Null(strings[0]);
@@ -512,7 +512,7 @@
             list.CopyTo(array, 0);
             NAssert.AreEqual(null, array[0]);

-            NAssert.True(StringValues.IsNullOrEmpty(strings));
+            NAssert.True(Strings.IsNullOrEmpty(strings));

             using (var e = strings.GetEnumerator())
             {
@@ -529,7 +529,7 @@
             public static void False(bool condition) => NAssert.False(condition);
             public static void Empty(IEnumerable collection) => NAssert.IsEmpty(collection);
             public static void Equal<T>(T expected, T actual) => NAssert.That(actual, Is.EqualTo(expected));
-            public static void Equal(string[] expected, StringValues actual) => NAssert.That(actual, Is.EqualTo(expected));
+            public static void Equal(string[] expected, Strings actual) => NAssert.That(actual, Is.EqualTo(expected));
             public static void Equal(string expected, string actual) => NAssert.AreEqual(actual, expected);
             public static void Throws<T>(TestDelegate code) where T : Exception => NAssert.Throws<T>(code);
             public static void Single<T>(IEnumerable<T> collection) => NAssert.That(collection.Count(), Is.EqualTo(1));


Update for change removing support for absolute paths in name transforms.

--- tests/Zip/ZipTests.cs
+++ tests/Zip/ZipTests.cs
@@ -419,6 +419,59 @@
 	#endregion

 	/// <summary>
+	/// This contains newer tests for stream handling. Much of this is still in GeneralHandling
+	/// </summary>
+	[TestFixture]
+	public class StreamHandling : ZipBase
+	{
+		void MustFailRead(Stream s, byte[] buffer, int offset, int count)
+		{
+			bool exception = false;
+			try {
+				s.Read(buffer, offset, count);
+			}
+			catch
+			{
+				exception = true;
+			}
+			Assert.IsTrue(exception, "Read should fail");
+		}
+
+		[Test]
+		public void ParameterHandling()
+		{
+			byte[] buffer = new byte[10];
+			byte[] emptyBuffer = new byte[0];
+
+			MemoryStream ms = new MemoryStream();
+			ZipOutputStream outStream = new ZipOutputStream(ms);
+			outStream.IsStreamOwner = false;
+			outStream.PutNextEntry(new ZipEntry("Floyd"));
+			outStream.Write(buffer, 0, 10);
+			outStream.Finish();
+
+			ms.Seek(0, SeekOrigin.Begin);
+
+			ZipInputStream inStream = new ZipInputStream(ms);
+			ZipEntry e = inStream.GetNextEntry();
+
+			MustFailRead(inStream, null, 0, 0);
+			MustFailRead(inStream, buffer, -1, 1);
+			MustFailRead(inStream, buffer, 0, 11);
+			MustFailRead(inStream, buffer, 7, 5);
+			MustFailRead(inStream, buffer, 0, -1);
+
+			MustFailRead(inStream, emptyBuffer, 0, 1);
+
+			int bytesRead = inStream.Read(buffer, 10, 0);
+			Assert.AreEqual(0, bytesRead, "Should be able to read zero bytes");
+
+			bytesRead = inStream.Read(emptyBuffer, 0, 0);
+			Assert.AreEqual(0, bytesRead, "Should be able to read zero bytes");
+		}
+	}
+
+	/// <summary>
 	/// This class contains test cases for Zip compression and decompression
 	/// </summary>
 	[TestFixture]
@@ -628,7 +681,7 @@
 			ZipEntry entry;
 			while ((entry = inStream.GetNextEntry()) != null)
 			{
-				Assert.IsNull(entry, "No entries should be found in empty zip");
+				Assert.Fail("No entries should be found in empty zip");
 			}
 		}

@@ -1206,6 +1259,16 @@
 			return result;
 		}

+		[Test]
+		[Category("Zip")]
+		public void NameTransforms()
+		{
+			INameTransform t = new ZipNameTransform(@"C:\Slippery");
+			Assert.AreEqual("Pongo/Directory/", t.TransformDirectory(@"C:\Slippery\Pongo\Directory"), "Value should be trimmed and converted");
+			Assert.AreEqual("PoNgo/Directory/", t.TransformDirectory(@"c:\slipperY\PoNgo\Directory"), "Trimming should be case insensitive");
+			Assert.AreEqual("slippery/Pongo/Directory/", t.TransformDirectory(@"d:\slippery\Pongo\Directory"), "Trimming should be case insensitive");
+		}
+
 		/// <summary>
 		/// Test ZipEntry static file name cleaning methods
 		/// </summary>
@@ -1217,8 +1280,6 @@
 			Assert.IsTrue(string.Compare(ZipEntry.CleanName(@"z:\eccles"), "eccles") == 0);
 			Assert.IsTrue(string.Compare(ZipEntry.CleanName(@"\\server\share\eccles"), "eccles") == 0);
 			Assert.IsTrue(string.Compare(ZipEntry.CleanName(@"\\server\share\dir\eccles"), "dir/eccles") == 0);
-			Assert.IsTrue(string.Compare(ZipEntry.CleanName(@"\\server\share\eccles", false), "/eccles") == 0);
-			Assert.IsTrue(string.Compare(ZipEntry.CleanName(@"c:\a\b\c\deus.dat", false), "/a/b/c/deus.dat") == 0);
 		}

 		void CheckNameConversion(string toCheck)


Payload can be split in between

Payload can be split in between

--- src/libfintx/Main.cs
+++ src/libfintx/Main.cs
@@ -165,8 +165,6 @@
             if (!result.IsSuccess)
                 return result.TypedResult<List<SWIFTStatement>>();

-            var swiftStatements = new List<SWIFTStatement>();
-
             var startDateStr = startDate?.ToString("yyyyMMdd");
             var endDateStr = endDate?.ToString("yyyyMMdd");

@@ -181,13 +179,12 @@
                 return result.TypedResult<List<SWIFTStatement>>();

             BankCode = result.RawData;
-            string Transactions;
-            if (BankCode.Contains("HNSHA"))
-                Transactions = ":20:" + Helper.Parse_String(BankCode, ":20:", "'HNSHA");
-            else // -> Postbank finishes with HNHBS
-                Transactions = ":20:" + Helper.Parse_String(BankCode, ":20:", "'HNHBS");
-
-            swiftStatements.AddRange(MT940.Serialize(Transactions, connectionDetails.Account, saveMt940File));
+            StringBuilder Transactions = new StringBuilder();
+
+            var regex = new Regex(@"HIKAZ:.+?@\d+@(\n|\r|\r\n)*(?<payload>.+?)('HNSHA|''HNHBS)", RegexOptions.Singleline);
+            var match = regex.Match(BankCode);
+            if (match.Success)
+                Transactions.Append(match.Groups["payload"].Value);

             string BankCode_ = BankCode;
             while (BankCode_.Contains("+3040::"))
@@ -206,15 +203,14 @@
                     return result.TypedResult<List<SWIFTStatement>>();

                 BankCode_ = result.RawData;
-                // Subsequent transactions can also begin with :61: (e.g. Berliner Sparkasse)
-                var startToken = ":20:";
-                if (BankCode_.Contains(":61:") && BankCode_.IndexOf(":61:") < BankCode_.IndexOf(":20:"))
-                    startToken = ":61:";
-
-                var Transactions_ = startToken + Helper.Parse_String(BankCode_, startToken, "'HNSHA");
-
-                swiftStatements.AddRange(MT940.Serialize(Transactions_, connectionDetails.Account));
+                match = regex.Match(BankCode_);
+                if (match.Success)
+                    Transactions.Append(match.Groups["payload"].Value);
             }
+
+            var swiftStatements = new List<SWIFTStatement>();
+
+            swiftStatements.AddRange(MT940.Serialize(Transactions.ToString(), connectionDetails.Account, saveMt940File));

             return result.TypedResult(swiftStatements);
         }


Made DumpAllEntities public for the ease of access.

Only works if the right flag is set anyways, so I see no danger
of abusing it. Also it creates a warning, so yeah, everything is well.

--- DemoInfo/DemoParser.cs
+++ DemoInfo/DemoParser.cs
@@ -805,7 +805,8 @@

 		}
 		#if SAVE_PROP_VALUES
-		private string DumpAllEntities()
+		[Obsolete("This method is only for debugging-purposes and shuld never be used in production, so you need to live with this warning.")]
+		public string DumpAllEntities()
 		{
 			StringBuilder res = new StringBuilder ();
 			for (int i = 0; i < MAX_ENTITIES; i++) {
@@ -835,9 +836,9 @@
 			return res.ToString();
 		}

-		private void DumpAllEntities(string fileName)
-		{
-
+		[Obsolete("This method is only for debugging-purposes and shuld never be used in production, so you need to live with this warning.")]
+		public void DumpAllEntities(string fileName)
+		{
 			StreamWriter writer = new StreamWriter(fileName);
 			writer.WriteLine(DumpAllEntities());
 			writer.Flush();


Added support for different parameter kinds.

--- src/Bridge/Function.cs
+++ src/Bridge/Function.cs
@@ -21,19 +21,31 @@
         Unknown
     }

+    public enum ParameterKind
+    {
+        Regular,
+    }
+
     public class Parameter : Declaration, ITypedDecl
     {
         public Parameter()
         {
+            Kind = ParameterKind.Regular;
             Usage = ParameterUsage.Unknown;
             HasDefaultValue = false;
         }

         public Type Type { get { return QualifiedType.Type; } }
         public QualifiedType QualifiedType { get; set; }
+
+        public ParameterKind Kind { get; set; }
         public ParameterUsage Usage { get; set; }
         public bool HasDefaultValue { get; set; }

+        public bool IsSynthetized
+        {
+            get { return Kind != ParameterKind.Regular; }
+        }

         public override T Visit<T>(IDeclVisitor<T> visitor)
         {


notify for sov time to start to keep the UI upto date with changes

--- EVEData/SOVCampaign.cs
+++ EVEData/SOVCampaign.cs
@@ -61,8 +61,23 @@
         }

+
+
         public DateTime StartTime { get; set; }
-        public TimeSpan TimeToStart { get; set; }
+
+        private TimeSpan m_TimeToStart;
+        public TimeSpan TimeToStart
+        {
+            get
+            {
+                return m_TimeToStart;
+            }
+            set
+            {
+                m_TimeToStart = value;
+                OnPropertyChanged("TimeToStart");
+            }
+        }

         private bool m_Valid;
         public bool Valid


Change default settings Usage from Required to Optional.

--- Eco/SettingsManager.cs
+++ Eco/SettingsManager.cs
@@ -24,7 +24,7 @@
         {
             _serializer = serializer;
             _serializationAttributesGenerator = serializationAttributesGenerator;
-            this.DefaultUsage = Usage.Required;
+            this.DefaultUsage = Usage.Optional;
             this.InitializeRawSettingsLoadVisitors();
             this.InitializeRefinedSettingsLoadVisitors();
             this.InitializeRefinedSettingsSaveVisitors();
@@ -77,7 +77,6 @@
             var namespaceMapBuilder = new NamespaceMapBuilder();
             this.RefinedSettingsWriteVisitors = new List<ITwinSettingsVisitor>
             {
-                new RequiredFieldChecker(),
                 new RawSettingsBuilder(),
                 namespaceMapBuilder,
                 new ReferencePacker(namespaceMapBuilder.NamespaceMap),


Make EditableText.Lines return a read-only list

--- Engine/EditableText.cs
+++ Engine/EditableText.cs
@@ -24,7 +24,7 @@
         /// <summary>
         /// The lines in the Text.
         /// </summary>
-        public string[] Lines { get { return lines.ToArray(); } }
+        public IList<string> Lines => lines.ReadOnly();

         /// <summary>
         /// The new line character in the Text.
@@ -118,8 +118,8 @@
                 throw new ArgumentNullException(nameof(range));
             }

-            return range.Start.Line <= Lines.Length
-                && range.End.Line <= Lines.Length
+            return range.Start.Line <= Lines.Count
+                && range.End.Line <= Lines.Count
                 && range.Start.Column <= Lines[range.Start.Line - 1].Length
                 && range.End.Column <= Lines[range.End.Line - 1].Length + 1;
         }


add license context

add license context

--- EverImage/GetImages.cs
+++ EverImage/GetImages.cs
@@ -1,4 +1,28 @@
-using System;
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2014 the-takeo
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+using System;
 using System.Collections.Generic;
 using System.ComponentModel;
 using System.Windows.Forms;


Add additional test case for smart indenting,

after multi line method calls, as discussed on the PR feedback.

--- src/EditorFeatures/CSharpTest/Formatting/Indentation/SmartIndenterTests.cs
+++ src/EditorFeatures/CSharpTest/Formatting/Indentation/SmartIndenterTests.cs
@@ -2743,6 +2743,29 @@
 {
     public void Test()
     {
+        new List<DateTime>()
+                .Where(d => d.Kind == DateTimeKind.Local ||
+                            d.Kind == DateTimeKind.Utc)
+
+                .ToArray();
+    }
+}";
+
+            AssertSmartIndent(
+                code: code,
+                indentationLine: 7,
+                expectedIndentation: 16);
+        }
+
+        [WpfFact]
+        [WorkItem(33253, "https://github.com/dotnet/roslyn/issues/33253")]
+        [Trait(Traits.Feature, Traits.Features.SmartIndent)]
+        public void EnterAfterFluentSequences_3()
+        {
+            var code = @"public class Test
+{
+    public void Test()
+    {
         new List<DateTime>().Where(d => d.Kind == DateTimeKind.Local ||
                                         d.Kind == DateTimeKind.Utc)

@@ -2759,7 +2782,7 @@
         [WpfFact]
         [WorkItem(33253, "https://github.com/dotnet/roslyn/issues/33253")]
         [Trait(Traits.Feature, Traits.Features.SmartIndent)]
-        public void EnterAfterFluentSequences_3()
+        public void EnterAfterFluentSequences_4()
         {
             var code = @"public class Test
 {


Fixed inline renames not using GetFinalSymbolName for the actual rename

Fixes #16460

--- src/EditorFeatures/Core/Implementation/InlineRename/InlineRenameSession.cs
+++ src/EditorFeatures/Core/Implementation/InlineRename/InlineRenameSession.cs
@@ -380,7 +380,7 @@
         {
             AssertIsForeground();
             VerifyNotDismissed();
-            this.ReplacementText = replacementText;
+            this.ReplacementText = _renameInfo.GetFinalSymbolName(replacementText);

             Action propagateEditAction = delegate
             {
@@ -587,7 +587,7 @@
                     newSolution = previewService.PreviewChanges(
                         string.Format(EditorFeaturesResources.Preview_Changes_0, EditorFeaturesResources.Rename),
                         "vs.csharp.refactoring.rename",
-                        string.Format(EditorFeaturesResources.Rename_0_to_1_colon, this.OriginalSymbolName, _renameInfo.GetFinalSymbolName(this.ReplacementText)),
+                        string.Format(EditorFeaturesResources.Rename_0_to_1_colon, this.OriginalSymbolName, this.ReplacementText),
                         _renameInfo.FullDisplayName,
                         _renameInfo.Glyph,
                         _conflictResolutionTask.Result.NewSolution,


Fixed an issue when the metadata value from a generic parameter was not properly set.

--- src/Kephas.Core/Services/Composition/AppServiceConventionsRegistrarBase.cs
+++ src/Kephas.Core/Services/Composition/AppServiceConventionsRegistrarBase.cs
@@ -390,15 +390,26 @@
         /// <returns>The metadata value.</returns>
         private object GetMetadataValueFromGenericParameter(Type type, int position, Type serviceContractType)
         {
-            var closedGeneric =
-                type.GetTypeInfo()
-                    .ImplementedInterfaces.Select(i => i.GetTypeInfo())
+            var typeInfo = type.GetTypeInfo();
+            var closedGeneric = typeInfo.ImplementedInterfaces
+                    .Select(i => i.GetTypeInfo())
                     .FirstOrDefault(
                         i =>
                         i.IsGenericType && !i.IsGenericTypeDefinition
                         && i.GetGenericTypeDefinition() == serviceContractType);

-            return closedGeneric?.GenericTypeArguments[position];
+            if (closedGeneric == null && type.IsConstructedGenericType && type.GetGenericTypeDefinition() == serviceContractType)
+            {
+                closedGeneric = typeInfo;
+            }
+
+            var genericArg = closedGeneric?.GenericTypeArguments[position];
+            if (genericArg?.IsGenericParameter ?? false)
+            {
+                genericArg = genericArg.GetTypeInfo().BaseType;
+            }
+
+            return genericArg;
         }

         /// <summary>


DNN-20086: GetPageDetails getting crashed with null object reference

--- src/Modules/Content/Dnn.PersonaBar.Pages/Components/PagesControllerImpl.cs
+++ src/Modules/Content/Dnn.PersonaBar.Pages/Components/PagesControllerImpl.cs
@@ -1027,14 +1027,15 @@

         public PageSettings GetPageSettings(int pageId, PortalSettings requestPortalSettings = null)
         {
-            var tab = GetPageDetails(pageId);
-
-            if (!_contentVerifier.IsContentExistsForRequestedPortal(tab.PortalID, requestPortalSettings))
+            var tab = GetPageDetails(pageId);
+
+            var portalSettings = requestPortalSettings ?? PortalController.Instance.GetCurrentPortalSettings();
+
+            if (!_contentVerifier.IsContentExistsForRequestedPortal(tab.PortalID, portalSettings))
             {
                 throw new PageNotFoundException();
             }
-
-            var portalSettings = PortalController.Instance.GetCurrentPortalSettings();
+
             var page = Converters.ConvertToPageSettings<PageSettings>(tab);
             page.Modules = GetModules(page.TabId).Select(Converters.ConvertToModuleItem);
             page.PageUrls = GetPageUrls(page.TabId);


Update ParamArrayAttribute.cs (#4442)

Update ParamArrayAttribute.cs (#4442)

A minor doc error (presumably some copy'n'paste issue).

--- src/mscorlib/src/System/ParamArrayAttribute.cs
+++ src/mscorlib/src/System/ParamArrayAttribute.cs
@@ -6,7 +6,7 @@
 **
 **
 **
-** Purpose: Container for assemblies.
+** Purpose: Attribute for multiple parameters.
 **
 **
 =============================================================================*/


minor improvements to debug logging

minor improvements to debug logging

--- src/Spring/Spring.Data/Transaction/Interceptor/TransactionAspectSupport.cs
+++ src/Spring/Spring.Data/Transaction/Interceptor/TransactionAspectSupport.cs
@@ -365,9 +365,9 @@
 	            // false. We created it only to preserve the integrity of
 	            // the ThreadLocal stack maintained in this class.
 	            if (log.IsDebugEnabled)
-	            {
-                    log.Debug("Don't need to create transaction for [" + joinpointIdentification +
-	                          "]: this method isn't transactional");
+	            {
+                    log.Debug("Skipping transactional joinpoint [" + joinpointIdentification +
+                              "] because no transaction manager has been configured");
 	            }
 	        }

@@ -408,8 +408,8 @@
                 #region Instrumentation

 			    if (log.IsDebugEnabled)
-			    {
-			        log.Debug("Invoking commit for transaction on " + transactionInfo.JoinpointIdentification);
+			    {
+                    log.Debug("Completing transaction for [" + transactionInfo.JoinpointIdentification + "]");
 			    }

 			    #endregion


Cleanup '#if CORE' in DynamicInstructionN.cs (#4423)

--- src/System.Management.Automation/engine/interpreter/DynamicInstructionN.cs
+++ src/System.Management.Automation/engine/interpreter/DynamicInstructionN.cs
@@ -15,9 +15,6 @@

 using System.Runtime.CompilerServices;

-#if CORECLR
-using System.Reflection;
-#endif

 namespace System.Management.Automation.Interpreter
 {


Update src/Workspaces/Core/Portable/EmbeddedLanguages/VirtualChars/VirtualChar.cs

Co-Authored-By: Sam Harwell <f16bed56189e249fe4ca8ed10a1ecae60e8ceac0@tunnelvisionlabs.com>

--- src/Workspaces/Core/Portable/EmbeddedLanguages/VirtualChars/VirtualChar.cs
+++ src/Workspaces/Core/Portable/EmbeddedLanguages/VirtualChars/VirtualChar.cs
@@ -37,7 +37,7 @@

         /// <summary>
         /// The unpaired high or low surrogate character that was encountered that could not be represented in <see
-        /// cref="Rune"/>.  If <see cref="Rune"/> is not <see cref="Rune.ReplacementChar"/> this will be <c>0</c>.
+        /// cref="Rune"/>.  If <see cref="Rune"/> is not <see cref="Rune.ReplacementChar"/>, this will be <c>0</c>.
         /// </summary>
         public readonly char SurrogateChar;