Minor

Minor

--- src/ProtocolBuffers/CodedInputStream.cs
+++ src/ProtocolBuffers/CodedInputStream.cs
@@ -1,977 +1,977 @@
-#region Copyright notice and license
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// http://github.com/jskeet/dotnet-protobufs/
-// Original C++/Java/Python code:
-// http://code.google.com/p/protobuf/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#endregion
-
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Text;
-using Google.ProtocolBuffers.Descriptors;
-
-namespace Google.ProtocolBuffers {
-
-  /// <summary>
-  /// Readings and decodes protocol message fields.
-  /// </summary>
-  /// <remarks>
-  /// This class contains two kinds of methods:  methods that read specific
-  /// protocol message constructs and field types (e.g. ReadTag and
-  /// ReadInt32) and methods that read low-level values (e.g.
-  /// ReadRawVarint32 and ReadRawBytes).  If you are reading encoded protocol
-  /// messages, you should use the former methods, but if you are reading some
-  /// other format of your own design, use the latter. The names of the former
-  /// methods are taken from the protocol buffer type names, not .NET types.
-  /// (Hence ReadFloat instead of ReadSingle, and ReadBool instead of ReadBoolean.)
-  ///
-  /// TODO(jonskeet): Consider whether recursion and size limits shouldn't be readonly,
-  /// set at construction time.
-  /// </remarks>
-  public sealed class CodedInputStream {
-    private readonly byte[] buffer;
-    private int bufferSize;
-    private int bufferSizeAfterLimit = 0;
-    private int bufferPos = 0;
-    private readonly Stream input;
+#region Copyright notice and license
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// http://github.com/jskeet/dotnet-protobufs/
+// Original C++/Java/Python code:
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+using Google.ProtocolBuffers.Descriptors;
+
+namespace Google.ProtocolBuffers {
+
+  /// <summary>
+  /// Readings and decodes protocol message fields.
+  /// </summary>
+  /// <remarks>
+  /// This class contains two kinds of methods:  methods that read specific
+  /// protocol message constructs and field types (e.g. ReadTag and
+  /// ReadInt32) and methods that read low-level values (e.g.
+  /// ReadRawVarint32 and ReadRawBytes).  If you are reading encoded protocol
+  /// messages, you should use the former methods, but if you are reading some
+  /// other format of your own design, use the latter. The names of the former
+  /// methods are taken from the protocol buffer type names, not .NET types.
+  /// (Hence ReadFloat instead of ReadSingle, and ReadBool instead of ReadBoolean.)
+  ///
+  /// TODO(jonskeet): Consider whether recursion and size limits shouldn't be readonly,
+  /// set at construction time.
+  /// </remarks>
+  public sealed class CodedInputStream {
+    private readonly byte[] buffer;
+    private int bufferSize;
+    private int bufferSizeAfterLimit = 0;
+    private int bufferPos = 0;
+    private readonly Stream input;
     private uint lastTag = 0;
 	private readonly ByteBuffer rawBytesBuffer = new ByteBuffer(new byte[BufferSize], 0, 0);
 	private readonly ByteStringStringInterning byteStringStringInterning = ByteStringStringInterning.CreateInstance();
-
-
-    internal const int DefaultRecursionLimit = 64;
-    internal const int DefaultSizeLimit = 64 << 20; // 64MB
-    internal const int BufferSize = 4096;
-
-    /// <summary>
-    /// The total number of bytes read before the current buffer. The
-    /// total bytes read up to the current position can be computed as
-    /// totalBytesRetired + bufferPos.
-    /// </summary>
-    private int totalBytesRetired = 0;
-
-    /// <summary>
-    /// The absolute position of the end of the current message.
-    /// </summary>
-    private int currentLimit = int.MaxValue;
-
-    /// <summary>
-    /// <see cref="SetRecursionLimit"/>
-    /// </summary>
-    private int recursionDepth = 0;
-    private int recursionLimit = DefaultRecursionLimit;
-
-    /// <summary>
-    /// <see cref="SetSizeLimit"/>
-    /// </summary>
-    private int sizeLimit = DefaultSizeLimit;
-
-    #region Construction
-    /// <summary>
-    /// Creates a new CodedInputStream reading data from the given
-    /// stream.
-    /// </summary>
-    public static CodedInputStream CreateInstance(Stream input) {
-      return new CodedInputStream(input);
-    }
-
-    /// <summary>
-    /// Creates a new CodedInputStream reading data from the given
-    /// byte array.
-    /// </summary>
-    public static CodedInputStream CreateInstance(byte[] buf) {
-      return new CodedInputStream(buf);
-    }
-
-    private CodedInputStream(byte[] buffer) {
-      this.buffer = buffer;
-      this.bufferSize = buffer.Length;
-      this.input = null;
-    }
-
-    private CodedInputStream(Stream input) {
-      this.buffer = new byte[BufferSize];
-      this.bufferSize = 0;
-      this.input = input;
-    }
-    #endregion
-
-    #region Validation
-    /// <summary>
-    /// Verifies that the last call to ReadTag() returned the given tag value.
-    /// This is used to verify that a nested group ended with the correct
-    /// end tag.
-    /// </summary>
-    /// <exception cref="InvalidProtocolBufferException">The last
-    /// tag read was not the one specified</exception>
-    [CLSCompliant(false)]
-    public void CheckLastTagWas(uint value) {
-      if (lastTag != value) {
-        throw InvalidProtocolBufferException.InvalidEndTag();
-      }
-    }
-    #endregion
-
-    #region Reading of tags etc
-    /// <summary>
-    /// Attempt to read a field tag, returning 0 if we have reached the end
-    /// of the input data. Protocol message parsers use this to read tags,
-    /// since a protocol message may legally end wherever a tag occurs, and
-    /// zero is not a valid tag number.
-    /// </summary>
-    [CLSCompliant(false)]
-    public uint ReadTag() {
-      if (IsAtEnd) {
-        lastTag = 0;
-        return 0;
-      }
-
-      lastTag = ReadRawVarint32();
-      if (lastTag == 0) {
-        // If we actually read zero, that's not a valid tag.
-        throw InvalidProtocolBufferException.InvalidTag();
-      }
-      return lastTag;
-    }
-
-    /// <summary>
-    /// Read a double field from the stream.
-    /// </summary>
-    public double ReadDouble() {
-#if SILVERLIGHT2 || COMPACT_FRAMEWORK_35
-      byte[] bytes = ReadRawBytes(8);
-      return BitConverter.ToDouble(bytes, 0);
-#else
-      return BitConverter.Int64BitsToDouble((long) ReadRawLittleEndian64());
-#endif
-    }
-
-    /// <summary>
-    /// Read a float field from the stream.
-    /// </summary>
-    public float ReadFloat() {
-      // TODO(jonskeet): Test this on different endiannesses
-      uint raw = ReadRawLittleEndian32();
-      byte[] rawBytes = BitConverter.GetBytes(raw);
-      return BitConverter.ToSingle(rawBytes, 0);
-    }
-
-    /// <summary>
-    /// Read a uint64 field from the stream.
-    /// </summary>
-    [CLSCompliant(false)]
-    public ulong ReadUInt64() {
-      return ReadRawVarint64();
-    }
-
-    /// <summary>
-    /// Read an int64 field from the stream.
-    /// </summary>
-    public long ReadInt64() {
-      return (long) ReadRawVarint64();
-    }
-
-    /// <summary>
-    /// Read an int32 field from the stream.
-    /// </summary>
-    public int ReadInt32() {
-      return (int) ReadRawVarint32();
-    }
-
-    /// <summary>
-    /// Read a fixed64 field from the stream.
-    /// </summary>
-    [CLSCompliant(false)]
-    public ulong ReadFixed64() {
-      return ReadRawLittleEndian64();
-    }
-
-    /// <summary>
-    /// Read a fixed32 field from the stream.
-    /// </summary>
-    [CLSCompliant(false)]
-    public uint ReadFixed32() {
-      return ReadRawLittleEndian32();
-    }
-
-    /// <summary>
-    /// Read a bool field from the stream.
-    /// </summary>
-    public bool ReadBool() {
-      return ReadRawVarint32() != 0;
-    }
-
-    /// <summary>
-    /// Reads a string field from the stream.
-    /// </summary>
-    public String ReadString() {
-      int size = (int) ReadRawVarint32();
-      // No need to read any data for an empty string.
-      if (size == 0) {
-        return "";
-      }
-      if (size <= bufferSize - bufferPos) {
-        // Fast path:  We already have the bytes in a contiguous buffer, so
+
+
+    internal const int DefaultRecursionLimit = 64;
+    internal const int DefaultSizeLimit = 64 << 20; // 64MB
+    internal const int BufferSize = 4096;
+
+    /// <summary>
+    /// The total number of bytes read before the current buffer. The
+    /// total bytes read up to the current position can be computed as
+    /// totalBytesRetired + bufferPos.
+    /// </summary>
+    private int totalBytesRetired = 0;
+
+    /// <summary>
+    /// The absolute position of the end of the current message.
+    /// </summary>
+    private int currentLimit = int.MaxValue;
+
+    /// <summary>
+    /// <see cref="SetRecursionLimit"/>
+    /// </summary>
+    private int recursionDepth = 0;
+    private int recursionLimit = DefaultRecursionLimit;
+
+    /// <summary>
+    /// <see cref="SetSizeLimit"/>
+    /// </summary>
+    private int sizeLimit = DefaultSizeLimit;
+
+    #region Construction
+    /// <summary>
+    /// Creates a new CodedInputStream reading data from the given
+    /// stream.
+    /// </summary>
+    public static CodedInputStream CreateInstance(Stream input) {
+      return new CodedInputStream(input);
+    }
+
+    /// <summary>
+    /// Creates a new CodedInputStream reading data from the given
+    /// byte array.
+    /// </summary>
+    public static CodedInputStream CreateInstance(byte[] buf) {
+      return new CodedInputStream(buf);
+    }
+
+    private CodedInputStream(byte[] buffer) {
+      this.buffer = buffer;
+      this.bufferSize = buffer.Length;
+      this.input = null;
+    }
+
+    private CodedInputStream(Stream input) {
+      this.buffer = new byte[BufferSize];
+      this.bufferSize = 0;
+      this.input = input;
+    }
+    #endregion
+
+    #region Validation
+    /// <summary>
+    /// Verifies that the last call to ReadTag() returned the given tag value.
+    /// This is used to verify that a nested group ended with the correct
+    /// end tag.
+    /// </summary>
+    /// <exception cref="InvalidProtocolBufferException">The last
+    /// tag read was not the one specified</exception>
+    [CLSCompliant(false)]
+    public void CheckLastTagWas(uint value) {
+      if (lastTag != value) {
+        throw InvalidProtocolBufferException.InvalidEndTag();
+      }
+    }
+    #endregion
+
+    #region Reading of tags etc
+    /// <summary>
+    /// Attempt to read a field tag, returning 0 if we have reached the end
+    /// of the input data. Protocol message parsers use this to read tags,
+    /// since a protocol message may legally end wherever a tag occurs, and
+    /// zero is not a valid tag number.
+    /// </summary>
+    [CLSCompliant(false)]
+    public uint ReadTag() {
+      if (IsAtEnd) {
+        lastTag = 0;
+        return 0;
+      }
+
+      lastTag = ReadRawVarint32();
+      if (lastTag == 0) {
+        // If we actually read zero, that's not a valid tag.
+        throw InvalidProtocolBufferException.InvalidTag();
+      }
+      return lastTag;
+    }
+
+    /// <summary>
+    /// Read a double field from the stream.
+    /// </summary>
+    public double ReadDouble() {
+#if SILVERLIGHT2 || COMPACT_FRAMEWORK_35
+      byte[] bytes = ReadRawBytes(8);
+      return BitConverter.ToDouble(bytes, 0);
+#else
+      return BitConverter.Int64BitsToDouble((long) ReadRawLittleEndian64());
+#endif
+    }
+
+    /// <summary>
+    /// Read a float field from the stream.
+    /// </summary>
+    public float ReadFloat() {
+      // TODO(jonskeet): Test this on different endiannesses
+      uint raw = ReadRawLittleEndian32();
+      byte[] rawBytes = BitConverter.GetBytes(raw);
+      return BitConverter.ToSingle(rawBytes, 0);
+    }
+
+    /// <summary>
+    /// Read a uint64 field from the stream.
+    /// </summary>
+    [CLSCompliant(false)]
+    public ulong ReadUInt64() {
+      return ReadRawVarint64();
+    }
+
+    /// <summary>
+    /// Read an int64 field from the stream.
+    /// </summary>
+    public long ReadInt64() {
+      return (long) ReadRawVarint64();
+    }
+
+    /// <summary>
+    /// Read an int32 field from the stream.
+    /// </summary>
+    public int ReadInt32() {
+      return (int) ReadRawVarint32();
+    }
+
+    /// <summary>
+    /// Read a fixed64 field from the stream.
+    /// </summary>
+    [CLSCompliant(false)]
+    public ulong ReadFixed64() {
+      return ReadRawLittleEndian64();
+    }
+
+    /// <summary>
+    /// Read a fixed32 field from the stream.
+    /// </summary>
+    [CLSCompliant(false)]
+    public uint ReadFixed32() {
+      return ReadRawLittleEndian32();
+    }
+
+    /// <summary>
+    /// Read a bool field from the stream.
+    /// </summary>
+    public bool ReadBool() {
+      return ReadRawVarint32() != 0;
+    }
+
+    /// <summary>
+    /// Reads a string field from the stream.
+    /// </summary>
+    public String ReadString() {
+      int size = (int) ReadRawVarint32();
+      // No need to read any data for an empty string.
+      if (size == 0) {
+        return "";
+      }
+      if (size <= bufferSize - bufferPos) {
+        // Fast path:  We already have the bytes in a contiguous buffer, so
         //   just copy directly from it.
-		  String result = byteStringStringInterning.Intern(new ByteBuffer(buffer, bufferPos, size));
-        bufferPos += size;
-        return result;
-      }
+		  String result = byteStringStringInterning.Intern(new ByteBuffer(buffer, bufferPos, size));
+        bufferPos += size;
+        return result;
+      }
       // Slow path: Build a byte array first then copy it.
-	  return byteStringStringInterning.Intern(ReadRawBytes(size));
-    }
-
-    /// <summary>
-    /// Reads a group field value from the stream.
-    /// </summary>
-    public void ReadGroup(int fieldNumber, IBuilder builder,
-                          ExtensionRegistry extensionRegistry) {
-      if (recursionDepth >= recursionLimit) {
-        throw InvalidProtocolBufferException.RecursionLimitExceeded();
-      }
-      ++recursionDepth;
-      builder.WeakMergeFrom(this, extensionRegistry);
-      CheckLastTagWas(WireFormat.MakeTag(fieldNumber, WireFormat.WireType.EndGroup));
-      --recursionDepth;
-    }
-
-    /// <summary>
-    /// Reads a group field value from the stream and merges it into the given
-    /// UnknownFieldSet.
-    /// </summary>
-    public void ReadUnknownGroup(int fieldNumber, UnknownFieldSet.Builder builder) {
-      if (recursionDepth >= recursionLimit) {
-        throw InvalidProtocolBufferException.RecursionLimitExceeded();
-      }
-      ++recursionDepth;
-      builder.MergeFrom(this);
-      CheckLastTagWas(WireFormat.MakeTag(fieldNumber, WireFormat.WireType.EndGroup));
-      --recursionDepth;
-    }
-
-    /// <summary>
-    /// Reads an embedded message field value from the stream.
-    /// </summary>
-    public void ReadMessage(IBuilder builder, ExtensionRegistry extensionRegistry) {
-      int length = (int) ReadRawVarint32();
-      if (recursionDepth >= recursionLimit) {
-        throw InvalidProtocolBufferException.RecursionLimitExceeded();
-      }
-      int oldLimit = PushLimit(length);
-      ++recursionDepth;
-      builder.WeakMergeFrom(this, extensionRegistry);
-      CheckLastTagWas(0);
-      --recursionDepth;
-      PopLimit(oldLimit);
-    }
-
-    /// <summary>
-    /// Reads a bytes field value from the stream.
-    /// </summary>
-    public ByteString ReadBytes() {
-      int size = (int) ReadRawVarint32();
-      if (size < bufferSize - bufferPos && size > 0) {
-        // Fast path:  We already have the bytes in a contiguous buffer, so
-        //   just copy directly from it.
-        ByteString result = ByteString.CopyFrom(buffer, bufferPos, size);
-        bufferPos += size;
-        return result;
-      } else {
+	  return byteStringStringInterning.Intern(ReadRawBytes(size));
+    }
+
+    /// <summary>
+    /// Reads a group field value from the stream.
+    /// </summary>
+    public void ReadGroup(int fieldNumber, IBuilder builder,
+                          ExtensionRegistry extensionRegistry) {
+      if (recursionDepth >= recursionLimit) {
+        throw InvalidProtocolBufferException.RecursionLimitExceeded();
+      }
+      ++recursionDepth;
+      builder.WeakMergeFrom(this, extensionRegistry);
+      CheckLastTagWas(WireFormat.MakeTag(fieldNumber, WireFormat.WireType.EndGroup));
+      --recursionDepth;
+    }
+
+    /// <summary>
+    /// Reads a group field value from the stream and merges it into the given
+    /// UnknownFieldSet.
+    /// </summary>
+    public void ReadUnknownGroup(int fieldNumber, UnknownFieldSet.Builder builder) {
+      if (recursionDepth >= recursionLimit) {
+        throw InvalidProtocolBufferException.RecursionLimitExceeded();
+      }
+      ++recursionDepth;
+      builder.MergeFrom(this);
+      CheckLastTagWas(WireFormat.MakeTag(fieldNumber, WireFormat.WireType.EndGroup));
+      --recursionDepth;
+    }
+
+    /// <summary>
+    /// Reads an embedded message field value from the stream.
+    /// </summary>
+    public void ReadMessage(IBuilder builder, ExtensionRegistry extensionRegistry) {
+      int length = (int) ReadRawVarint32();
+      if (recursionDepth >= recursionLimit) {
+        throw InvalidProtocolBufferException.RecursionLimitExceeded();
+      }
+      int oldLimit = PushLimit(length);
+      ++recursionDepth;
+      builder.WeakMergeFrom(this, extensionRegistry);
+      CheckLastTagWas(0);
+      --recursionDepth;
+      PopLimit(oldLimit);
+    }
+
+    /// <summary>
+    /// Reads a bytes field value from the stream.
+    /// </summary>
+    public ByteString ReadBytes() {
+      int size = (int) ReadRawVarint32();
+      if (size < bufferSize - bufferPos && size > 0) {
+        // Fast path:  We already have the bytes in a contiguous buffer, so
+        //   just copy directly from it.
+        ByteString result = ByteString.CopyFrom(buffer, bufferPos, size);
+        bufferPos += size;
+        return result;
+      } else {
         // Slow path:  Build a byte array first then copy it.
-		ByteBuffer rawBytes = ReadRawBytes(size);
-        return ByteString.CopyFrom(rawBytes.Buffer, rawBytes.Offset, rawBytes.Length);
-      }
-    }
-
-    /// <summary>
-    /// Reads a uint32 field value from the stream.
-    /// </summary>
-    [CLSCompliant(false)]
-    public uint ReadUInt32() {
-      return ReadRawVarint32();
-    }
-
-    /// <summary>
-    /// Reads an enum field value from the stream. The caller is responsible
-    /// for converting the numeric value to an actual enum.
-    /// </summary>
-    public int ReadEnum() {
-      return (int) ReadRawVarint32();
-    }
-
-    /// <summary>
-    /// Reads an sfixed32 field value from the stream.
-    /// </summary>
-    public int ReadSFixed32() {
-      return (int) ReadRawLittleEndian32();
-    }
-
-    /// <summary>
-    /// Reads an sfixed64 field value from the stream.
-    /// </summary>
-    public long ReadSFixed64() {
-      return (long) ReadRawLittleEndian64();
-    }
-
-    /// <summary>
-    /// Reads an sint32 field value from the stream.
-    /// </summary>
-    public int ReadSInt32() {
-      return DecodeZigZag32(ReadRawVarint32());
-    }
-
-    /// <summary>
-    /// Reads an sint64 field value from the stream.
-    /// </summary>
-    public long ReadSInt64() {
-      return DecodeZigZag64(ReadRawVarint64());
-    }
-
-    /// <summary>
-    /// Reads a field of any primitive type. Enums, groups and embedded
-    /// messages are not handled by this method.
-    /// </summary>
-    public object ReadPrimitiveField(FieldType fieldType) {
-      switch (fieldType) {
-        case FieldType.Double:   return ReadDouble();
-        case FieldType.Float:    return ReadFloat();
-        case FieldType.Int64:    return ReadInt64();
-        case FieldType.UInt64:   return ReadUInt64();
-        case FieldType.Int32:    return ReadInt32();
-        case FieldType.Fixed64:  return ReadFixed64();
-        case FieldType.Fixed32:  return ReadFixed32();
-        case FieldType.Bool:     return ReadBool();
-        case FieldType.String:   return ReadString();
-        case FieldType.Bytes:    return ReadBytes();
-        case FieldType.UInt32:   return ReadUInt32();
-        case FieldType.SFixed32: return ReadSFixed32();
-        case FieldType.SFixed64: return ReadSFixed64();
-        case FieldType.SInt32:   return ReadSInt32();
-        case FieldType.SInt64:   return ReadSInt64();
-        case FieldType.Group:
-            throw new ArgumentException("ReadPrimitiveField() cannot handle nested groups.");
-        case FieldType.Message:
-            throw new ArgumentException("ReadPrimitiveField() cannot handle embedded messages.");
-        // We don't handle enums because we don't know what to do if the
-        // value is not recognized.
-        case FieldType.Enum:
-            throw new ArgumentException("ReadPrimitiveField() cannot handle enums.");
-        default:
-          throw new ArgumentOutOfRangeException("Invalid field type " + fieldType);
-      }
-    }
-
-    #endregion
-
-    #region Underlying reading primitives
-
-    /// <summary>
-    /// Same code as ReadRawVarint32, but read each byte individually, checking for
-    /// buffer overflow.
-    /// </summary>
-    private uint SlowReadRawVarint32() {
-      int tmp = ReadRawByte();
-      if (tmp < 128) {
-        return (uint)tmp;
-      }
-      int result = tmp & 0x7f;
-      if ((tmp = ReadRawByte()) < 128) {
-        result |= tmp << 7;
-      } else {
-        result |= (tmp & 0x7f) << 7;
-        if ((tmp = ReadRawByte()) < 128) {
-          result |= tmp << 14;
-        } else {
-          result |= (tmp & 0x7f) << 14;
-          if ((tmp = ReadRawByte()) < 128) {
-            result |= tmp << 21;
-          } else {
-            result |= (tmp & 0x7f) << 21;
-            result |= (tmp = ReadRawByte()) << 28;
-            if (tmp >= 128) {
-              // Discard upper 32 bits.
-              for (int i = 0; i < 5; i++) {
-                if (ReadRawByte() < 128) return (uint)result;
-              }
-              throw InvalidProtocolBufferException.MalformedVarint();
-            }
-          }
-        }
-      }
-      return (uint)result;
-    }
-
-    /// <summary>
-    /// Read a raw Varint from the stream.  If larger than 32 bits, discard the upper bits.
-    /// This method is optimised for the case where we've got lots of data in the buffer.
-    /// That means we can check the size just once, then just read directly from the buffer
-    /// without constant rechecking of the buffer length.
-    /// </summary>
-    [CLSCompliant(false)]
-    public uint ReadRawVarint32() {
-      if (bufferPos + 5 > bufferSize) {
-        return SlowReadRawVarint32();
-      }
-
-      int tmp = buffer[bufferPos++];
-      if (tmp < 128) {
-        return (uint)tmp;
-      }
-      int result = tmp & 0x7f;
-      if ((tmp = buffer[bufferPos++]) < 128) {
-        result |= tmp << 7;
-      } else {
-        result |= (tmp & 0x7f) << 7;
-        if ((tmp = buffer[bufferPos++]) < 128) {
-          result |= tmp << 14;
-        } else {
-          result |= (tmp & 0x7f) << 14;
-          if ((tmp = buffer[bufferPos++]) < 128) {
-            result |= tmp << 21;
-          } else {
-            result |= (tmp & 0x7f) << 21;
-            result |= (tmp = buffer[bufferPos++]) << 28;
-            if (tmp >= 128) {
-              // Discard upper 32 bits.
-              // Note that this has to use ReadRawByte() as we only ensure we've
-              // got at least 5 bytes at the start of the method. This lets us
-              // use the fast path in more cases, and we rarely hit this section of code.
-              for (int i = 0; i < 5; i++) {
-                if (ReadRawByte() < 128) return (uint)result;
-              }
-              throw InvalidProtocolBufferException.MalformedVarint();
-            }
-          }
-        }
-      }
-      return (uint)result;
-    }
-
-    /// <summary>
-    /// Reads a varint from the input one byte at a time, so that it does not
-    /// read any bytes after the end of the varint. If you simply wrapped the
-    /// stream in a CodedInputStream and used ReadRawVarint32(Stream)}
-    /// then you would probably end up reading past the end of the varint since
-    /// CodedInputStream buffers its input.
-    /// </summary>
-    /// <param name="input"></param>
-    /// <returns></returns>
-    internal static uint ReadRawVarint32(Stream input) {
-      int result = 0;
-      int offset = 0;
-      for (; offset < 32; offset += 7) {
-        int b = input.ReadByte();
-        if (b == -1) {
-          throw InvalidProtocolBufferException.TruncatedMessage();
-        }
-        result |= (b & 0x7f) << offset;
-        if ((b & 0x80) == 0) {
-          return (uint) result;
-        }
-      }
-      // Keep reading up to 64 bits.
-      for (; offset < 64; offset += 7) {
-        int b = input.ReadByte();
-        if (b == -1) {
-          throw InvalidProtocolBufferException.TruncatedMessage();
-        }
-        if ((b & 0x80) == 0) {
-          return (uint) result;
-        }
-      }
-      throw InvalidProtocolBufferException.MalformedVarint();
-    }
-
-    /// <summary>
-    /// Read a raw varint from the stream.
-    /// </summary>
-    [CLSCompliant(false)]
-    public ulong ReadRawVarint64() {
-      int shift = 0;
-      ulong result = 0;
-      while (shift < 64) {
-        byte b = ReadRawByte();
-        result |= (ulong)(b & 0x7F) << shift;
-        if ((b & 0x80) == 0) {
-          return result;
-        }
-        shift += 7;
-      }
-      throw InvalidProtocolBufferException.MalformedVarint();
-    }
-
-    /// <summary>
-    /// Read a 32-bit little-endian integer from the stream.
-    /// </summary>
-    [CLSCompliant(false)]
-    public uint ReadRawLittleEndian32() {
-      uint b1 = ReadRawByte();
-      uint b2 = ReadRawByte();
-      uint b3 = ReadRawByte();
-      uint b4 = ReadRawByte();
-      return b1 | (b2 << 8) | (b3 << 16) | (b4 << 24);
-    }
-
-    /// <summary>
-    /// Read a 64-bit little-endian integer from the stream.
-    /// </summary>
-    [CLSCompliant(false)]
-    public ulong ReadRawLittleEndian64() {
-      ulong b1 = ReadRawByte();
-      ulong b2 = ReadRawByte();
-      ulong b3 = ReadRawByte();
-      ulong b4 = ReadRawByte();
-      ulong b5 = ReadRawByte();
-      ulong b6 = ReadRawByte();
-      ulong b7 = ReadRawByte();
-      ulong b8 = ReadRawByte();
-      return b1 | (b2 << 8) | (b3 << 16) | (b4 << 24)
-          | (b5 << 32) | (b6 << 40) | (b7 << 48) | (b8 << 56);
-    }
-    #endregion
-
-    /// <summary>
-    /// Decode a 32-bit value with ZigZag encoding.
-    /// </summary>
-    /// <remarks>
-    /// ZigZag encodes signed integers into values that can be efficiently
-    /// encoded with varint.  (Otherwise, negative values must be
-    /// sign-extended to 64 bits to be varint encoded, thus always taking
-    /// 10 bytes on the wire.)
-    /// </remarks>
-    [CLSCompliant(false)]
-    public static int DecodeZigZag32(uint n) {
-      return (int)(n >> 1) ^ -(int)(n & 1);
-    }
-
-    /// <summary>
-    /// Decode a 32-bit value with ZigZag encoding.
-    /// </summary>
-    /// <remarks>
-    /// ZigZag encodes signed integers into values that can be efficiently
-    /// encoded with varint.  (Otherwise, negative values must be
-    /// sign-extended to 64 bits to be varint encoded, thus always taking
-    /// 10 bytes on the wire.)
-    /// </remarks>
-    [CLSCompliant(false)]
-    public static long DecodeZigZag64(ulong n) {
-      return (long)(n >> 1) ^ -(long)(n & 1);
-    }
-
-    /// <summary>
-    /// Set the maximum message recursion depth.
-    /// </summary>
-    /// <remarks>
-    /// In order to prevent malicious
-    /// messages from causing stack overflows, CodedInputStream limits
-    /// how deeply messages may be nested.  The default limit is 64.
-    /// </remarks>
-    public int SetRecursionLimit(int limit) {
-      if (limit < 0) {
-        throw new ArgumentOutOfRangeException("Recursion limit cannot be negative: " + limit);
-      }
-      int oldLimit = recursionLimit;
-      recursionLimit = limit;
-      return oldLimit;
-    }
-
-    /// <summary>
-    /// Set the maximum message size.
-    /// </summary>
-    /// <remarks>
-    /// In order to prevent malicious messages from exhausting memory or
-    /// causing integer overflows, CodedInputStream limits how large a message may be.
-    /// The default limit is 64MB.  You should set this limit as small
-    /// as you can without harming your app's functionality.  Note that
-    /// size limits only apply when reading from an InputStream, not
-    /// when constructed around a raw byte array (nor with ByteString.NewCodedInput).
-    /// If you want to read several messages from a single CodedInputStream, you
-    /// can call ResetSizeCounter() after each message to avoid hitting the
-    /// size limit.
-    /// </remarks>
-    public int SetSizeLimit(int limit) {
-      if (limit < 0) {
-        throw new ArgumentOutOfRangeException("Size limit cannot be negative: " + limit);
-      }
-      int oldLimit = sizeLimit;
-      sizeLimit = limit;
-      return oldLimit;
-    }
-
-    #region Internal reading and buffer management
-    /// <summary>
-    /// Resets the current size counter to zero (see SetSizeLimit).
-    /// </summary>
-    public void ResetSizeCounter() {
-      totalBytesRetired = 0;
-    }
-
-    /// <summary>
-    /// Sets currentLimit to (current position) + byteLimit. This is called
-    /// when descending into a length-delimited embedded message. The previous
-    /// limit is returned.
-    /// </summary>
-    /// <returns>The old limit.</returns>
-    public int PushLimit(int byteLimit) {
-      if (byteLimit < 0) {
-        throw InvalidProtocolBufferException.NegativeSize();
-      }
-      byteLimit += totalBytesRetired + bufferPos;
-      int oldLimit = currentLimit;
-      if (byteLimit > oldLimit) {
-        throw InvalidProtocolBufferException.TruncatedMessage();
-      }
-      currentLimit = byteLimit;
-
-      RecomputeBufferSizeAfterLimit();
-
-      return oldLimit;
-    }
-
-    private void RecomputeBufferSizeAfterLimit() {
-      bufferSize += bufferSizeAfterLimit;
-      int bufferEnd = totalBytesRetired + bufferSize;
-      if (bufferEnd > currentLimit) {
-        // Limit is in current buffer.
-        bufferSizeAfterLimit = bufferEnd - currentLimit;
-        bufferSize -= bufferSizeAfterLimit;
-      } else {
-        bufferSizeAfterLimit = 0;
-      }
-    }
-
-    /// <summary>
-    /// Discards the current limit, returning the previous limit.
-    /// </summary>
-    public void PopLimit(int oldLimit) {
-      currentLimit = oldLimit;
-      RecomputeBufferSizeAfterLimit();
-    }
-
-    /// <summary>
-    /// Returns whether or not all the data before the limit has been read.
-    /// </summary>
-    /// <returns></returns>
-    public bool ReachedLimit {
-      get {
-        if (currentLimit == int.MaxValue) {
-          return false;
-        }
-        int currentAbsolutePosition = totalBytesRetired + bufferPos;
-        return currentAbsolutePosition >= currentLimit;
-      }
-    }
-
-    /// <summary>
-    /// Returns true if the stream has reached the end of the input. This is the
-    /// case if either the end of the underlying input source has been reached or
-    /// the stream has reached a limit created using PushLimit.
-    /// </summary>
-    public bool IsAtEnd {
-      get {
-        return bufferPos == bufferSize && !RefillBuffer(false);
-      }
-    }
-
-    /// <summary>
-    /// Called when buffer is empty to read more bytes from the
-    /// input.  If <paramref name="mustSucceed"/> is true, RefillBuffer() gurantees that
-    /// either there will be at least one byte in the buffer when it returns
-    /// or it will throw an exception.  If <paramref name="mustSucceed"/> is false,
-    /// RefillBuffer() returns false if no more bytes were available.
-    /// </summary>
-    /// <param name="mustSucceed"></param>
-    /// <returns></returns>
-    private bool RefillBuffer(bool mustSucceed)  {
-      if (bufferPos < bufferSize) {
-        throw new InvalidOperationException("RefillBuffer() called when buffer wasn't empty.");
-      }
-
-      if (totalBytesRetired + bufferSize == currentLimit) {
-        // Oops, we hit a limit.
-        if (mustSucceed) {
-          throw InvalidProtocolBufferException.TruncatedMessage();
-        } else {
-          return false;
-        }
-      }
-
-      totalBytesRetired += bufferSize;
-
-      bufferPos = 0;
-      bufferSize = (input == null) ? 0 : input.Read(buffer, 0, buffer.Length);
-      if (bufferSize < 0) {
-        throw new InvalidOperationException("Stream.Read returned a negative count");
-      }
-      if (bufferSize == 0) {
-        if (mustSucceed) {
-          throw InvalidProtocolBufferException.TruncatedMessage();
-        } else {
-          return false;
-        }
-      } else {
-        RecomputeBufferSizeAfterLimit();
-        int totalBytesRead =
-          totalBytesRetired + bufferSize + bufferSizeAfterLimit;
-        if (totalBytesRead > sizeLimit || totalBytesRead < 0) {
-          throw InvalidProtocolBufferException.SizeLimitExceeded();
-        }
-        return true;
-      }
-    }
-
-    /// <summary>
-    /// Read one byte from the input.
-    /// </summary>
-    /// <exception cref="InvalidProtocolBufferException">
-    /// the end of the stream or the current limit was reached
-    /// </exception>
-    public byte ReadRawByte() {
-      if (bufferPos == bufferSize) {
-        RefillBuffer(true);
-      }
-      return buffer[bufferPos++];
-    }
-
-    /// <summary>
-    /// Read a fixed size of bytes from the input.
-    /// </summary>
-    /// <exception cref="InvalidProtocolBufferException">
-    /// the end of the stream or the current limit was reached
-    /// </exception>
-    public ByteBuffer ReadRawBytes(int size) {
-      if (size < 0) {
-        throw InvalidProtocolBufferException.NegativeSize();
-      }
-
-      if (totalBytesRetired + bufferPos + size > currentLimit) {
-        // Read to the end of the stream anyway.
-        SkipRawBytes(currentLimit - totalBytesRetired - bufferPos);
-        // Then fail.
-        throw InvalidProtocolBufferException.TruncatedMessage();
-      }
-
-      if (size <= bufferSize - bufferPos) {
+		ByteBuffer rawBytes = ReadRawBytes(size);
+        return ByteString.CopyFrom(rawBytes.Buffer, rawBytes.Offset, rawBytes.Length);
+      }
+    }
+
+    /// <summary>
+    /// Reads a uint32 field value from the stream.
+    /// </summary>
+    [CLSCompliant(false)]
+    public uint ReadUInt32() {
+      return ReadRawVarint32();
+    }
+
+    /// <summary>
+    /// Reads an enum field value from the stream. The caller is responsible
+    /// for converting the numeric value to an actual enum.
+    /// </summary>
+    public int ReadEnum() {
+      return (int) ReadRawVarint32();
+    }
+
+    /// <summary>
+    /// Reads an sfixed32 field value from the stream.
+    /// </summary>
+    public int ReadSFixed32() {
+      return (int) ReadRawLittleEndian32();
+    }
+
+    /// <summary>
+    /// Reads an sfixed64 field value from the stream.
+    /// </summary>
+    public long ReadSFixed64() {
+      return (long) ReadRawLittleEndian64();
+    }
+
+    /// <summary>
+    /// Reads an sint32 field value from the stream.
+    /// </summary>
+    public int ReadSInt32() {
+      return DecodeZigZag32(ReadRawVarint32());
+    }
+
+    /// <summary>
+    /// Reads an sint64 field value from the stream.
+    /// </summary>
+    public long ReadSInt64() {
+      return DecodeZigZag64(ReadRawVarint64());
+    }
+
+    /// <summary>
+    /// Reads a field of any primitive type. Enums, groups and embedded
+    /// messages are not handled by this method.
+    /// </summary>
+    public object ReadPrimitiveField(FieldType fieldType) {
+      switch (fieldType) {
+        case FieldType.Double:   return ReadDouble();
+        case FieldType.Float:    return ReadFloat();
+        case FieldType.Int64:    return ReadInt64();
+        case FieldType.UInt64:   return ReadUInt64();
+        case FieldType.Int32:    return ReadInt32();
+        case FieldType.Fixed64:  return ReadFixed64();
+        case FieldType.Fixed32:  return ReadFixed32();
+        case FieldType.Bool:     return ReadBool();
+        case FieldType.String:   return ReadString();
+        case FieldType.Bytes:    return ReadBytes();
+        case FieldType.UInt32:   return ReadUInt32();
+        case FieldType.SFixed32: return ReadSFixed32();
+        case FieldType.SFixed64: return ReadSFixed64();
+        case FieldType.SInt32:   return ReadSInt32();
+        case FieldType.SInt64:   return ReadSInt64();
+        case FieldType.Group:
+            throw new ArgumentException("ReadPrimitiveField() cannot handle nested groups.");
+        case FieldType.Message:
+            throw new ArgumentException("ReadPrimitiveField() cannot handle embedded messages.");
+        // We don't handle enums because we don't know what to do if the
+        // value is not recognized.
+        case FieldType.Enum:
+            throw new ArgumentException("ReadPrimitiveField() cannot handle enums.");
+        default:
+          throw new ArgumentOutOfRangeException("Invalid field type " + fieldType);
+      }
+    }
+
+    #endregion
+
+    #region Underlying reading primitives
+
+    /// <summary>
+    /// Same code as ReadRawVarint32, but read each byte individually, checking for
+    /// buffer overflow.
+    /// </summary>
+    private uint SlowReadRawVarint32() {
+      int tmp = ReadRawByte();
+      if (tmp < 128) {
+        return (uint)tmp;
+      }
+      int result = tmp & 0x7f;
+      if ((tmp = ReadRawByte()) < 128) {
+        result |= tmp << 7;
+      } else {
+        result |= (tmp & 0x7f) << 7;
+        if ((tmp = ReadRawByte()) < 128) {
+          result |= tmp << 14;
+        } else {
+          result |= (tmp & 0x7f) << 14;
+          if ((tmp = ReadRawByte()) < 128) {
+            result |= tmp << 21;
+          } else {
+            result |= (tmp & 0x7f) << 21;
+            result |= (tmp = ReadRawByte()) << 28;
+            if (tmp >= 128) {
+              // Discard upper 32 bits.
+              for (int i = 0; i < 5; i++) {
+                if (ReadRawByte() < 128) return (uint)result;
+              }
+              throw InvalidProtocolBufferException.MalformedVarint();
+            }
+          }
+        }
+      }
+      return (uint)result;
+    }
+
+    /// <summary>
+    /// Read a raw Varint from the stream.  If larger than 32 bits, discard the upper bits.
+    /// This method is optimised for the case where we've got lots of data in the buffer.
+    /// That means we can check the size just once, then just read directly from the buffer
+    /// without constant rechecking of the buffer length.
+    /// </summary>
+    [CLSCompliant(false)]
+    public uint ReadRawVarint32() {
+      if (bufferPos + 5 > bufferSize) {
+        return SlowReadRawVarint32();
+      }
+
+      int tmp = buffer[bufferPos++];
+      if (tmp < 128) {
+        return (uint)tmp;
+      }
+      int result = tmp & 0x7f;
+      if ((tmp = buffer[bufferPos++]) < 128) {
+        result |= tmp << 7;
+      } else {
+        result |= (tmp & 0x7f) << 7;
+        if ((tmp = buffer[bufferPos++]) < 128) {
+          result |= tmp << 14;
+        } else {
+          result |= (tmp & 0x7f) << 14;
+          if ((tmp = buffer[bufferPos++]) < 128) {
+            result |= tmp << 21;
+          } else {
+            result |= (tmp & 0x7f) << 21;
+            result |= (tmp = buffer[bufferPos++]) << 28;
+            if (tmp >= 128) {
+              // Discard upper 32 bits.
+              // Note that this has to use ReadRawByte() as we only ensure we've
+              // got at least 5 bytes at the start of the method. This lets us
+              // use the fast path in more cases, and we rarely hit this section of code.
+              for (int i = 0; i < 5; i++) {
+                if (ReadRawByte() < 128) return (uint)result;
+              }
+              throw InvalidProtocolBufferException.MalformedVarint();
+            }
+          }
+        }
+      }
+      return (uint)result;
+    }
+
+    /// <summary>
+    /// Reads a varint from the input one byte at a time, so that it does not
+    /// read any bytes after the end of the varint. If you simply wrapped the
+    /// stream in a CodedInputStream and used ReadRawVarint32(Stream)}
+    /// then you would probably end up reading past the end of the varint since
+    /// CodedInputStream buffers its input.
+    /// </summary>
+    /// <param name="input"></param>
+    /// <returns></returns>
+    internal static uint ReadRawVarint32(Stream input) {
+      int result = 0;
+      int offset = 0;
+      for (; offset < 32; offset += 7) {
+        int b = input.ReadByte();
+        if (b == -1) {
+          throw InvalidProtocolBufferException.TruncatedMessage();
+        }
+        result |= (b & 0x7f) << offset;
+        if ((b & 0x80) == 0) {
+          return (uint) result;
+        }
+      }
+      // Keep reading up to 64 bits.
+      for (; offset < 64; offset += 7) {
+        int b = input.ReadByte();
+        if (b == -1) {
+          throw InvalidProtocolBufferException.TruncatedMessage();
+        }
+        if ((b & 0x80) == 0) {
+          return (uint) result;
+        }
+      }
+      throw InvalidProtocolBufferException.MalformedVarint();
+    }
+
+    /// <summary>
+    /// Read a raw varint from the stream.
+    /// </summary>
+    [CLSCompliant(false)]
+    public ulong ReadRawVarint64() {
+      int shift = 0;
+      ulong result = 0;
+      while (shift < 64) {
+        byte b = ReadRawByte();
+        result |= (ulong)(b & 0x7F) << shift;
+        if ((b & 0x80) == 0) {
+          return result;
+        }
+        shift += 7;
+      }
+      throw InvalidProtocolBufferException.MalformedVarint();
+    }
+
+    /// <summary>
+    /// Read a 32-bit little-endian integer from the stream.
+    /// </summary>
+    [CLSCompliant(false)]
+    public uint ReadRawLittleEndian32() {
+      uint b1 = ReadRawByte();
+      uint b2 = ReadRawByte();
+      uint b3 = ReadRawByte();
+      uint b4 = ReadRawByte();
+      return b1 | (b2 << 8) | (b3 << 16) | (b4 << 24);
+    }
+
+    /// <summary>
+    /// Read a 64-bit little-endian integer from the stream.
+    /// </summary>
+    [CLSCompliant(false)]
+    public ulong ReadRawLittleEndian64() {
+      ulong b1 = ReadRawByte();
+      ulong b2 = ReadRawByte();
+      ulong b3 = ReadRawByte();
+      ulong b4 = ReadRawByte();
+      ulong b5 = ReadRawByte();
+      ulong b6 = ReadRawByte();
+      ulong b7 = ReadRawByte();
+      ulong b8 = ReadRawByte();
+      return b1 | (b2 << 8) | (b3 << 16) | (b4 << 24)
+          | (b5 << 32) | (b6 << 40) | (b7 << 48) | (b8 << 56);
+    }
+    #endregion
+
+    /// <summary>
+    /// Decode a 32-bit value with ZigZag encoding.
+    /// </summary>
+    /// <remarks>
+    /// ZigZag encodes signed integers into values that can be efficiently
+    /// encoded with varint.  (Otherwise, negative values must be
+    /// sign-extended to 64 bits to be varint encoded, thus always taking
+    /// 10 bytes on the wire.)
+    /// </remarks>
+    [CLSCompliant(false)]
+    public static int DecodeZigZag32(uint n) {
+      return (int)(n >> 1) ^ -(int)(n & 1);
+    }
+
+    /// <summary>
+    /// Decode a 32-bit value with ZigZag encoding.
+    /// </summary>
+    /// <remarks>
+    /// ZigZag encodes signed integers into values that can be efficiently
+    /// encoded with varint.  (Otherwise, negative values must be
+    /// sign-extended to 64 bits to be varint encoded, thus always taking
+    /// 10 bytes on the wire.)
+    /// </remarks>
+    [CLSCompliant(false)]
+    public static long DecodeZigZag64(ulong n) {
+      return (long)(n >> 1) ^ -(long)(n & 1);
+    }
+
+    /// <summary>
+    /// Set the maximum message recursion depth.
+    /// </summary>
+    /// <remarks>
+    /// In order to prevent malicious
+    /// messages from causing stack overflows, CodedInputStream limits
+    /// how deeply messages may be nested.  The default limit is 64.
+    /// </remarks>
+    public int SetRecursionLimit(int limit) {
+      if (limit < 0) {
+        throw new ArgumentOutOfRangeException("Recursion limit cannot be negative: " + limit);
+      }
+      int oldLimit = recursionLimit;
+      recursionLimit = limit;
+      return oldLimit;
+    }
+
+    /// <summary>
+    /// Set the maximum message size.
+    /// </summary>
+    /// <remarks>
+    /// In order to prevent malicious messages from exhausting memory or
+    /// causing integer overflows, CodedInputStream limits how large a message may be.
+    /// The default limit is 64MB.  You should set this limit as small
+    /// as you can without harming your app's functionality.  Note that
+    /// size limits only apply when reading from an InputStream, not
+    /// when constructed around a raw byte array (nor with ByteString.NewCodedInput).
+    /// If you want to read several messages from a single CodedInputStream, you
+    /// can call ResetSizeCounter() after each message to avoid hitting the
+    /// size limit.
+    /// </remarks>
+    public int SetSizeLimit(int limit) {
+      if (limit < 0) {
+        throw new ArgumentOutOfRangeException("Size limit cannot be negative: " + limit);
+      }
+      int oldLimit = sizeLimit;
+      sizeLimit = limit;
+      return oldLimit;
+    }
+
+    #region Internal reading and buffer management
+    /// <summary>
+    /// Resets the current size counter to zero (see SetSizeLimit).
+    /// </summary>
+    public void ResetSizeCounter() {
+      totalBytesRetired = 0;
+    }
+
+    /// <summary>
+    /// Sets currentLimit to (current position) + byteLimit. This is called
+    /// when descending into a length-delimited embedded message. The previous
+    /// limit is returned.
+    /// </summary>
+    /// <returns>The old limit.</returns>
+    public int PushLimit(int byteLimit) {
+      if (byteLimit < 0) {
+        throw InvalidProtocolBufferException.NegativeSize();
+      }
+      byteLimit += totalBytesRetired + bufferPos;
+      int oldLimit = currentLimit;
+      if (byteLimit > oldLimit) {
+        throw InvalidProtocolBufferException.TruncatedMessage();
+      }
+      currentLimit = byteLimit;
+
+      RecomputeBufferSizeAfterLimit();
+
+      return oldLimit;
+    }
+
+    private void RecomputeBufferSizeAfterLimit() {
+      bufferSize += bufferSizeAfterLimit;
+      int bufferEnd = totalBytesRetired + bufferSize;
+      if (bufferEnd > currentLimit) {
+        // Limit is in current buffer.
+        bufferSizeAfterLimit = bufferEnd - currentLimit;
+        bufferSize -= bufferSizeAfterLimit;
+      } else {
+        bufferSizeAfterLimit = 0;
+      }
+    }
+
+    /// <summary>
+    /// Discards the current limit, returning the previous limit.
+    /// </summary>
+    public void PopLimit(int oldLimit) {
+      currentLimit = oldLimit;
+      RecomputeBufferSizeAfterLimit();
+    }
+
+    /// <summary>
+    /// Returns whether or not all the data before the limit has been read.
+    /// </summary>
+    /// <returns></returns>
+    public bool ReachedLimit {
+      get {
+        if (currentLimit == int.MaxValue) {
+          return false;
+        }
+        int currentAbsolutePosition = totalBytesRetired + bufferPos;
+        return currentAbsolutePosition >= currentLimit;
+      }
+    }
+
+    /// <summary>
+    /// Returns true if the stream has reached the end of the input. This is the
+    /// case if either the end of the underlying input source has been reached or
+    /// the stream has reached a limit created using PushLimit.
+    /// </summary>
+    public bool IsAtEnd {
+      get {
+        return bufferPos == bufferSize && !RefillBuffer(false);
+      }
+    }
+
+    /// <summary>
+    /// Called when buffer is empty to read more bytes from the
+    /// input.  If <paramref name="mustSucceed"/> is true, RefillBuffer() gurantees that
+    /// either there will be at least one byte in the buffer when it returns
+    /// or it will throw an exception.  If <paramref name="mustSucceed"/> is false,
+    /// RefillBuffer() returns false if no more bytes were available.
+    /// </summary>
+    /// <param name="mustSucceed"></param>
+    /// <returns></returns>
+    private bool RefillBuffer(bool mustSucceed)  {
+      if (bufferPos < bufferSize) {
+        throw new InvalidOperationException("RefillBuffer() called when buffer wasn't empty.");
+      }
+
+      if (totalBytesRetired + bufferSize == currentLimit) {
+        // Oops, we hit a limit.
+        if (mustSucceed) {
+          throw InvalidProtocolBufferException.TruncatedMessage();
+        } else {
+          return false;
+        }
+      }
+
+      totalBytesRetired += bufferSize;
+
+      bufferPos = 0;
+      bufferSize = (input == null) ? 0 : input.Read(buffer, 0, buffer.Length);
+      if (bufferSize < 0) {
+        throw new InvalidOperationException("Stream.Read returned a negative count");
+      }
+      if (bufferSize == 0) {
+        if (mustSucceed) {
+          throw InvalidProtocolBufferException.TruncatedMessage();
+        } else {
+          return false;
+        }
+      } else {
+        RecomputeBufferSizeAfterLimit();
+        int totalBytesRead =
+          totalBytesRetired + bufferSize + bufferSizeAfterLimit;
+        if (totalBytesRead > sizeLimit || totalBytesRead < 0) {
+          throw InvalidProtocolBufferException.SizeLimitExceeded();
+        }
+        return true;
+      }
+    }
+
+    /// <summary>
+    /// Read one byte from the input.
+    /// </summary>
+    /// <exception cref="InvalidProtocolBufferException">
+    /// the end of the stream or the current limit was reached
+    /// </exception>
+    public byte ReadRawByte() {
+      if (bufferPos == bufferSize) {
+        RefillBuffer(true);
+      }
+      return buffer[bufferPos++];
+    }
+
+    /// <summary>
+    /// Read a fixed size of bytes from the input.
+    /// </summary>
+    /// <exception cref="InvalidProtocolBufferException">
+    /// the end of the stream or the current limit was reached
+    /// </exception>
+    public ByteBuffer ReadRawBytes(int size) {
+      if (size < 0) {
+        throw InvalidProtocolBufferException.NegativeSize();
+      }
+
+      if (totalBytesRetired + bufferPos + size > currentLimit) {
+        // Read to the end of the stream anyway.
+        SkipRawBytes(currentLimit - totalBytesRetired - bufferPos);
+        // Then fail.
+        throw InvalidProtocolBufferException.TruncatedMessage();
+      }
+
+      if (size <= bufferSize - bufferPos) {
         // We have all the bytes we need already.
 		  var result = new ByteBuffer(buffer, bufferPos, size);
 		  bufferPos += size;
-		  return result;
-      } else if (size < BufferSize) {
-        // Reading more bytes than are in the buffer, but not an excessive number
-        // of bytes.  We can safely allocate the resulting array ahead of time.
-
+		  return result;
+      } else if (size < BufferSize) {
+        // Reading more bytes than are in the buffer, but not an excessive number
+        // of bytes.  We can safely allocate the resulting array ahead of time.
+
         // First copy what we have.
 		rawBytesBuffer.Length = size;
 		rawBytesBuffer.Offset = 0;
-        int pos = bufferSize - bufferPos;
-        Array.Copy(buffer, bufferPos, rawBytesBuffer.Buffer, 0, pos);
-        bufferPos = bufferSize;
-
-        // We want to use RefillBuffer() and then copy from the buffer into our
-        // byte array rather than reading directly into our byte array because
-        // the input may be unbuffered.
-        RefillBuffer(true);
-
-        while (size - pos > bufferSize) {
-          Array.Copy(buffer, 0, rawBytesBuffer.Buffer, pos, bufferSize);
-          pos += bufferSize;
-          bufferPos = bufferSize;
-          RefillBuffer(true);
-        }
-
-        Array.Copy(buffer, 0, rawBytesBuffer.Buffer, pos, size - pos);
+        int pos = bufferSize - bufferPos;
+        Array.Copy(buffer, bufferPos, rawBytesBuffer.Buffer, 0, pos);
+        bufferPos = bufferSize;
+
+        // We want to use RefillBuffer() and then copy from the buffer into our
+        // byte array rather than reading directly into our byte array because
+        // the input may be unbuffered.
+        RefillBuffer(true);
+
+        while (size - pos > bufferSize) {
+          Array.Copy(buffer, 0, rawBytesBuffer.Buffer, pos, bufferSize);
+          pos += bufferSize;
+          bufferPos = bufferSize;
+          RefillBuffer(true);
+        }
+
+        Array.Copy(buffer, 0, rawBytesBuffer.Buffer, pos, size - pos);
         bufferPos = size - pos;
-      	rawBytesBuffer.ResetHash();
-        return rawBytesBuffer;
-      } else {
-        // The size is very large.  For security reasons, we can't allocate the
-        // entire byte array yet.  The size comes directly from the input, so a
-        // maliciously-crafted message could provide a bogus very large size in
-        // order to trick the app into allocating a lot of memory.  We avoid this
-        // by allocating and reading only a small chunk at a time, so that the
-        // malicious message must actually *be* extremely large to cause
-        // problems.  Meanwhile, we limit the allowed size of a message elsewhere.
-
-        // Remember the buffer markers since we'll have to copy the bytes out of
-        // it later.
-        int originalBufferPos = bufferPos;
-        int originalBufferSize = bufferSize;
-
-        // Mark the current buffer consumed.
-        totalBytesRetired += bufferSize;
-        bufferPos = 0;
-        bufferSize = 0;
-
-        // Read all the rest of the bytes we need.
-        int sizeLeft = size - (originalBufferSize - originalBufferPos);
-        List<byte[]> chunks = new List<byte[]>();
-
-        while (sizeLeft > 0) {
-          byte[] chunk = new byte[Math.Min(sizeLeft, BufferSize)];
-          int pos = 0;
-          while (pos < chunk.Length) {
-            int n = (input == null) ? -1 : input.Read(chunk, pos, chunk.Length - pos);
-            if (n <= 0) {
-              throw InvalidProtocolBufferException.TruncatedMessage();
-            }
-            totalBytesRetired += n;
-            pos += n;
-          }
-          sizeLeft -= chunk.Length;
-          chunks.Add(chunk);
-        }
-
-        // OK, got everything.  Now concatenate it all into one buffer.
-        byte[] bytes = new byte[size];
-
-        // Start by copying the leftover bytes from this.buffer.
-        int newPos = originalBufferSize - originalBufferPos;
-        Array.Copy(buffer, originalBufferPos, bytes, 0, newPos);
-
-        // And now all the chunks.
-        foreach (byte[] chunk in chunks) {
-          Array.Copy(chunk, 0, bytes, newPos, chunk.Length);
-          newPos += chunk.Length;
-        }
-
-        // Done.
-        return new ByteBuffer(bytes, 0, size);
-      }
-    }
-
-    /// <summary>
-    /// Reads and discards a single field, given its tag value.
-    /// </summary>
-    /// <returns>false if the tag is an end-group tag, in which case
-    /// nothing is skipped. Otherwise, returns true.</returns>
-    [CLSCompliant(false)]
-    public bool SkipField(uint tag) {
-      switch (WireFormat.GetTagWireType(tag)) {
-        case WireFormat.WireType.Varint:
-          ReadInt32();
-          return true;
-        case WireFormat.WireType.Fixed64:
-          ReadRawLittleEndian64();
-          return true;
-        case WireFormat.WireType.LengthDelimited:
-          SkipRawBytes((int) ReadRawVarint32());
-          return true;
-        case WireFormat.WireType.StartGroup:
-          SkipMessage();
-          CheckLastTagWas(
-            WireFormat.MakeTag(WireFormat.GetTagFieldNumber(tag),
-                               WireFormat.WireType.EndGroup));
-          return true;
-        case WireFormat.WireType.EndGroup:
-          return false;
-        case WireFormat.WireType.Fixed32:
-          ReadRawLittleEndian32();
-          return true;
-        default:
-          throw InvalidProtocolBufferException.InvalidWireType();
-      }
-    }
-
-    /// <summary>
-    /// Reads and discards an entire message.  This will read either until EOF
-    /// or until an endgroup tag, whichever comes first.
-    /// </summary>
-    public void SkipMessage() {
-      while (true) {
-        uint tag = ReadTag();
-        if (tag == 0 || !SkipField(tag)) {
-          return;
-        }
-      }
-    }
-
-    /// <summary>
-    /// Reads and discards <paramref name="size"/> bytes.
-    /// </summary>
-    /// <exception cref="InvalidProtocolBufferException">the end of the stream
-    /// or the current limit was reached</exception>
-    public void SkipRawBytes(int size) {
-      if (size < 0) {
-        throw InvalidProtocolBufferException.NegativeSize();
-      }
-
-      if (totalBytesRetired + bufferPos + size > currentLimit) {
-        // Read to the end of the stream anyway.
-        SkipRawBytes(currentLimit - totalBytesRetired - bufferPos);
-        // Then fail.
-        throw InvalidProtocolBufferException.TruncatedMessage();
-      }
-
-      if (size <= bufferSize - bufferPos) {
-        // We have all the bytes we need already.
-        bufferPos += size;
-      } else {
-        // Skipping more bytes than are in the buffer.  First skip what we have.
-        int pos = bufferSize - bufferPos;
-        totalBytesRetired += pos;
-        bufferPos = 0;
-        bufferSize = 0;
-
-        // Then skip directly from the InputStream for the rest.
-        if (pos < size) {
-          if (input == null) {
-            throw InvalidProtocolBufferException.TruncatedMessage();
-          }
-          SkipImpl(size - pos);
-          totalBytesRetired += size - pos;
-        }
-      }
-    }
-
-    /// <summary>
-    /// Abstraction of skipping to cope with streams which can't really skip.
-    /// </summary>
-    private void SkipImpl(int amountToSkip) {
-      if (input.CanSeek) {
-        long previousPosition = input.Position;
-        input.Position += amountToSkip;
-        if (input.Position != previousPosition + amountToSkip) {
-          throw InvalidProtocolBufferException.TruncatedMessage();
-        }
-      } else {
-        byte[] skipBuffer = new byte[1024];
-        while (amountToSkip > 0) {
-          int bytesRead = input.Read(skipBuffer, 0, skipBuffer.Length);
-          if (bytesRead <= 0) {
-            throw InvalidProtocolBufferException.TruncatedMessage();
-          }
-          amountToSkip -= bytesRead;
-        }
-      }
-    }
-    #endregion
-  }
-}
+      	rawBytesBuffer.ResetHash();
+        return rawBytesBuffer;
+      } else {
+        // The size is very large.  For security reasons, we can't allocate the
+        // entire byte array yet.  The size comes directly from the input, so a
+        // maliciously-crafted message could provide a bogus very large size in
+        // order to trick the app into allocating a lot of memory.  We avoid this
+        // by allocating and reading only a small chunk at a time, so that the
+        // malicious message must actually *be* extremely large to cause
+        // problems.  Meanwhile, we limit the allowed size of a message elsewhere.
+
+        // Remember the buffer markers since we'll have to copy the bytes out of
+        // it later.
+        int originalBufferPos = bufferPos;
+        int originalBufferSize = bufferSize;
+
+        // Mark the current buffer consumed.
+        totalBytesRetired += bufferSize;
+        bufferPos = 0;
+        bufferSize = 0;
+
+        // Read all the rest of the bytes we need.
+        int sizeLeft = size - (originalBufferSize - originalBufferPos);
+        List<byte[]> chunks = new List<byte[]>();
+
+        while (sizeLeft > 0) {
+          byte[] chunk = new byte[Math.Min(sizeLeft, BufferSize)];
+          int pos = 0;
+          while (pos < chunk.Length) {
+            int n = (input == null) ? -1 : input.Read(chunk, pos, chunk.Length - pos);
+            if (n <= 0) {
+              throw InvalidProtocolBufferException.TruncatedMessage();
+            }
+            totalBytesRetired += n;
+            pos += n;
+          }
+          sizeLeft -= chunk.Length;
+          chunks.Add(chunk);
+        }
+
+        // OK, got everything.  Now concatenate it all into one buffer.
+        byte[] bytes = new byte[size];
+
+        // Start by copying the leftover bytes from this.buffer.
+        int newPos = originalBufferSize - originalBufferPos;
+        Array.Copy(buffer, originalBufferPos, bytes, 0, newPos);
+
+        // And now all the chunks.
+        foreach (byte[] chunk in chunks) {
+          Array.Copy(chunk, 0, bytes, newPos, chunk.Length);
+          newPos += chunk.Length;
+        }
+
+        // Done.
+        return new ByteBuffer(bytes, 0, size);
+      }
+    }
+
+    /// <summary>
+    /// Reads and discards a single field, given its tag value.
+    /// </summary>
+    /// <returns>false if the tag is an end-group tag, in which case
+    /// nothing is skipped. Otherwise, returns true.</returns>
+    [CLSCompliant(false)]
+    public bool SkipField(uint tag) {
+      switch (WireFormat.GetTagWireType(tag)) {
+        case WireFormat.WireType.Varint:
+          ReadInt32();
+          return true;
+        case WireFormat.WireType.Fixed64:
+          ReadRawLittleEndian64();
+          return true;
+        case WireFormat.WireType.LengthDelimited:
+          SkipRawBytes((int) ReadRawVarint32());
+          return true;
+        case WireFormat.WireType.StartGroup:
+          SkipMessage();
+          CheckLastTagWas(
+            WireFormat.MakeTag(WireFormat.GetTagFieldNumber(tag),
+                               WireFormat.WireType.EndGroup));
+          return true;
+        case WireFormat.WireType.EndGroup:
+          return false;
+        case WireFormat.WireType.Fixed32:
+          ReadRawLittleEndian32();
+          return true;
+        default:
+          throw InvalidProtocolBufferException.InvalidWireType();
+      }
+    }
+
+    /// <summary>
+    /// Reads and discards an entire message.  This will read either until EOF
+    /// or until an endgroup tag, whichever comes first.
+    /// </summary>
+    public void SkipMessage() {
+      while (true) {
+        uint tag = ReadTag();
+        if (tag == 0 || !SkipField(tag)) {
+          return;
+        }
+      }
+    }
+
+    /// <summary>
+    /// Reads and discards <paramref name="size"/> bytes.
+    /// </summary>
+    /// <exception cref="InvalidProtocolBufferException">the end of the stream
+    /// or the current limit was reached</exception>
+    public void SkipRawBytes(int size) {
+      if (size < 0) {
+        throw InvalidProtocolBufferException.NegativeSize();
+      }
+
+      if (totalBytesRetired + bufferPos + size > currentLimit) {
+        // Read to the end of the stream anyway.
+        SkipRawBytes(currentLimit - totalBytesRetired - bufferPos);
+        // Then fail.
+        throw InvalidProtocolBufferException.TruncatedMessage();
+      }
+
+      if (size <= bufferSize - bufferPos) {
+        // We have all the bytes we need already.
+        bufferPos += size;
+      } else {
+        // Skipping more bytes than are in the buffer.  First skip what we have.
+        int pos = bufferSize - bufferPos;
+        totalBytesRetired += pos;
+        bufferPos = 0;
+        bufferSize = 0;
+
+        // Then skip directly from the InputStream for the rest.
+        if (pos < size) {
+          if (input == null) {
+            throw InvalidProtocolBufferException.TruncatedMessage();
+          }
+          SkipImpl(size - pos);
+          totalBytesRetired += size - pos;
+        }
+      }
+    }
+
+    /// <summary>
+    /// Abstraction of skipping to cope with streams which can't really skip.
+    /// </summary>
+    private void SkipImpl(int amountToSkip) {
+      if (input.CanSeek) {
+        long previousPosition = input.Position;
+        input.Position += amountToSkip;
+        if (input.Position != previousPosition + amountToSkip) {
+          throw InvalidProtocolBufferException.TruncatedMessage();
+        }
+      } else {
+        byte[] skipBuffer = new byte[1024];
+        while (amountToSkip > 0) {
+          int bytesRead = input.Read(skipBuffer, 0, skipBuffer.Length);
+          if (bytesRead <= 0) {
+            throw InvalidProtocolBufferException.TruncatedMessage();
+          }
+          amountToSkip -= bytesRead;
+        }
+      }
+    }
+    #endregion
+  }
+}


Fix help command (#19)

Fix help command (#19)

--- src/SIM.Client/ParseArgumentsCommand.cs
+++ src/SIM.Client/ParseArgumentsCommand.cs
@@ -56,7 +56,7 @@
         BrowseCommandFacade,
         ConfigCommandFacade,
         DeleteCommandFacade,
-        InstallModuleCommandFacade,
+        InstallCommandFacade,
         InstallModuleCommandFacade,
         ListCommandFacade,
         LoginCommandFacade,
@@ -67,6 +67,7 @@
         StopCommandFacade,
         SyncCommandFacade
       >(Args);
+
       return result;
     }
   }


removendo chamada não necessária

removendo chamada não necessária

--- src/StaticCommons/Validation/Numeric.cs
+++ src/StaticCommons/Validation/Numeric.cs
@@ -1,10 +1,7 @@
-using System;
-
-namespace StaticCommons.Validation
+namespace StaticCommons.Validation
 {
     public static class Numeric
     {
-        static Numeric(){}
         public static bool StringIsAnNumber(string input)
         {
             int value;


changes.

changes.

--- src/TWCore/Services/ServiceContainer.cs
+++ src/TWCore/Services/ServiceContainer.cs
@@ -274,6 +274,7 @@
         /// </summary>
         /// <param name="showSettings">Show current settings</param>
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        [StackFrameLog("")]
         protected internal virtual void ShowFullHeader(bool showSettings = true)
         {
             var strArgs = _currentArgs.Join(" ");
@@ -361,6 +362,7 @@
         /// </summary>
         /// <param name="args">Run arguments</param>
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        [StackFrameLog("")]
         protected internal virtual void InternalRun(string[] args)
         {
             Core.Log.LibDebug("««« Starting Service »»»");
@@ -395,6 +397,7 @@
         }

         [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        [StackFrameLog("")]
         private void ServiceStartWithConsole()
         {
             Core.Log.InfoBasic(string.Empty);
@@ -462,6 +465,7 @@
             }
         }
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        [StackFrameLog("")]
         private void ServiceStartNoConsole()
         {
             var mres = new ManualResetEventSlim(false);


updated documentation about ThreadIDs

updated documentation about ThreadIDs

--- src/WipperSnapper/SQL/ConnectionPool.cs
+++ src/WipperSnapper/SQL/ConnectionPool.cs
@@ -13,7 +13,7 @@
 	/// - Connections need to be assigned per thread. We can't have a connection shared between 2 threads due to transaction boundaries.
 	/// - We have to be very careful with who we give connections to so that we don't violate a possible transaction by opening multiple connections in 1 transaction.
 	/// - We can have multiple connections with the same database but multiple things going on in that connection.
-	/// - Thread IDs are NOT unique
+	/// - ThreadIDs are only unique for the lifetime of the thread. I just don't think we care if a new-yet-finished thread uses the connection of the old thread.
 	/// </remarks>
 	public sealed class ConnectionPool
 	{


Fixed demo url issue

Fixed demo url issue

--- src/YuukoResume/Views/Home/Index.cshtml
+++ src/YuukoResume/Views/Home/Index.cshtml
@@ -226,7 +226,7 @@
                                                                     @(new HtmlString("   "))
                                                                      @x.ElementAt(i).GitHub.Replace("https://github.com/", "")
                                                                 }
-                                                                @if (!string.IsNullOrWhiteSpace(x.ElementAt(i).GitHub))
+                                                                @if (!string.IsNullOrWhiteSpace(x.ElementAt(i).DemoUrl))
                                                                 {
                                                                     @(new HtmlString("   "))
                                                                      Demo


Add parens to declare operator precedence

--- osu.Game/OsuGame.cs
+++ osu.Game/OsuGame.cs
@@ -654,7 +654,7 @@
                                         if (!(ScreenStack.CurrentScreen is IOsuScreen currentScreen))
                                             return;

-                                        if (!((Drawable)currentScreen).IsLoaded || currentScreen.AllowBackButton && !currentScreen.OnBackButton())
+                                        if (!((Drawable)currentScreen).IsLoaded || (currentScreen.AllowBackButton && !currentScreen.OnBackButton()))
                                             ScreenStack.Exit();
                                     }
                                 },


InBatch includes ThreadSafty.DoLocked, add bracket for if statement

--- src/Couchbase.Lite.Shared/API/Database/Database.cs
+++ src/Couchbase.Lite.Shared/API/Database/Database.cs
@@ -749,7 +749,7 @@
         public void Purge(string docId)
         {
             CBDebug.MustNotBeNull(Log.To.Database, Tag, nameof(docId), docId);
-            ThreadSafety.DoLocked(() => InBatch(() => PurgeDocById(docId)));
+            InBatch(() => PurgeDocById(docId));
         }

         /// <summary>
@@ -791,8 +791,9 @@
         /// doesn't exist</exception>
         public DateTimeOffset? GetDocumentExpiration(string docId)
         {
-            if (LiteCoreBridge.Check(err => Native.c4doc_get(_c4db, docId, true, err)) == null)
+            if (LiteCoreBridge.Check(err => Native.c4doc_get(_c4db, docId, true, err)) == null) {
                 throw new CouchbaseLiteException(C4ErrorCode.NotFound);
+            }
             var res = (long)Native.c4doc_getExpiration(_c4db, docId);
             if (res == 0) {
                 return null;


Fix a test that was using the previous error code

--- src/Couchbase.Lite.Tests.Shared/ReplicationTest.cs
+++ src/Couchbase.Lite.Tests.Shared/ReplicationTest.cs
@@ -516,10 +516,10 @@

             var config = CreateFailureP2PConfiguration(ProtocolType.ByteStream, MockConnectionLifecycleLocation.Close,
                 false);
-            RunReplication(config, (int)CouchbaseLiteError.WebSocketAbnormalClose, CouchbaseLiteErrorType.CouchbaseLite);
+            RunReplication(config, (int)CouchbaseLiteError.WebSocketUserPermanent, CouchbaseLiteErrorType.CouchbaseLite);
             config = CreateFailureP2PConfiguration(ProtocolType.MessageStream, MockConnectionLifecycleLocation.Close,
                 false);
-            RunReplication(config, (int)CouchbaseLiteError.WebSocketAbnormalClose, CouchbaseLiteErrorType.CouchbaseLite, true);
+            RunReplication(config, (int)CouchbaseLiteError.WebSocketUserPermanent, CouchbaseLiteErrorType.CouchbaseLite, true);
         }

         [Fact]


Changed default encoding for EmbeddedScriptProvider from ANSI to UTF8

--- src/DbUp/ScriptProviders/EmbeddedScriptProvider.cs
+++ src/DbUp/ScriptProviders/EmbeddedScriptProvider.cs
@@ -15,7 +15,7 @@
         /// </summary>
         /// <param name="assembly">The assembly.</param>
         /// <param name="filter">The filter.</param>
-        public EmbeddedScriptProvider(Assembly assembly, Func<string, bool> filter) : this(assembly, filter, Encoding.Default)
+        public EmbeddedScriptProvider(Assembly assembly, Func<string, bool> filter) : this(assembly, filter, Encoding.UTF8)
         {
         }


fixed mysql message queue executor bug. #66

--- src/DotNetCore.CAP.MySql/MySqlStorageConnection.cs
+++ src/DotNetCore.CAP.MySql/MySqlStorageConnection.cs
@@ -60,6 +60,7 @@

             using (var connection = new MySqlConnection(Options.ConnectionString))
             {
+                connection.Execute("SELECT LAST_INSERT_ID(0)");
                 return await connection.QueryFirstOrDefaultAsync<CapPublishedMessage>(sql);
             }
         }
@@ -105,6 +106,7 @@

             using (var connection = new MySqlConnection(Options.ConnectionString))
             {
+                connection.Execute("SELECT LAST_INSERT_ID(0)");
                 return await connection.QueryFirstOrDefaultAsync<CapReceivedMessage>(sql);
             }
         }


Fixed a concurrency problem with AssetManager.


stanford problem set 2

stanford problem set 2

--- sources/coursera-princeton-algorithms-1/csharp/Assignements/UnitTest1.cs
+++ sources/coursera-princeton-algorithms-1/csharp/Assignements/UnitTest1.cs
@@ -578,6 +578,126 @@
         {
             return $"[{string.Join(",", array.Select(x => x.ToString()).ToArray())}]";
         }
+
+        /// <summary>
+        /// You are given an n by n grid of distinct numbers.
+        /// A number is a local minimum if it is smaller than
+        /// all of its neighbors. (A neighbor of a number is one
+        /// immediately above, below, to the left, or the
+        /// right. Most numbers have four neighbors; numbers
+        /// on the side have three; the four corners have two.)
+        /// Use the divide-and-conquer algorithm design paradigm
+        /// to compute a local minimum with only O(n) comparisons
+        /// between pairs of numbers. (Note: since there are n2
+        /// numbers in the input, you cannot afford to look at
+        /// all of them.
+        /// Hint: Think about what types of recurrences would
+        /// give you the desired upper bound.)
+        /// </summary>
+        [TestMethod]
+        public void LowerestInMatrix()
+        {
+            var matrix = Parse(@"
+5 5 5 5 5 5 5 5
+5 4 4 4 4 4 5 5
+5 4 4 3 4 4 5 5
+5 4 4 4 4 4 5 5
+5 4 4 4 4 4 5 5
+5 4 4 4 4 4 5 5
+5 4 4 4 4 4 5 5
+5 4 4 4 4 4 5 5");
+            localminimunCount = 0;
+            var r = FindLocalMinimun(new MatrixReader(matrix), 0);
+            Console.WriteLine($"Cmparisons = {localminimunCount}");
+            Assert.IsTrue(r);
+        }
+
+        int localminimunCount = 0;
+
+        private bool FindLocalMinimun(MatrixReader matrix, int rec)
+        {
+            Console.Write($"{new string(' ', rec * 3)} {matrix.X},{matrix.Y},{matrix.W},{matrix.H}");
+            if ((matrix.W <= 1) && (matrix.H <= 1))
+            {
+                var result = matrix.islower(0, 0);
+                localminimunCount += 4;
+                Console.WriteLine($" - {matrix._(0, 0)} = {result}");
+                return result;
+            }
+            else
+            {
+                Console.WriteLine();
+            }
+
+            var qs = matrix.GetQuadrants().ToArray();
+            var rq1 = FindLocalMinimun(qs[0], rec + 1);
+            var rq2 = FindLocalMinimun(qs[1], rec + 1);
+            var rq3 = FindLocalMinimun(qs[2], rec + 1);
+            var rq4 = FindLocalMinimun(qs[3], rec + 1);
+
+            return rq1 || rq2 || rq3 || rq4;
+        }
+
+        public class MatrixReader
+        {
+            int[][] Data;
+            public int X;
+            public int Y;
+            public int W;
+            public int H;
+
+            public MatrixReader(int[][] data)
+                : this(data, 0, 0, data.Length, data[0].Length)
+            {
+            }
+
+            public MatrixReader(int[][] data, int x, int y, int w, int h)
+            {
+                Data = data;
+                X = x; Y = y; W = w; H = h;
+            }
+
+            public int _(int x, int y)
+            {
+                var lx = X + x;
+                var ly = Y + y;
+                if (lx < 0) return int.MaxValue;
+                if (ly < 0) return int.MaxValue;
+                if (lx >= Data[0].Length) return int.MaxValue;
+                if (ly >= Data.Length) return int.MaxValue;
+                return Data[Y + y][lx];
+            }
+
+            public IEnumerable<MatrixReader> GetQuadrants()
+            {
+                int mx = W / 2;
+                int my = H / 2;
+                yield return new MatrixReader(Data, X, Y, mx, my);
+                yield return new MatrixReader(Data, X + mx, Y, mx, my);
+                yield return new MatrixReader(Data, X, Y + my, mx, my);
+                yield return new MatrixReader(Data, X + mx, Y + my, mx, my);
+            }
+
+            internal bool islower(int x, int y)
+            {
+                var l = _(x - 1, y) > _(x, y);
+                var r = _(x + 1, y) > _(x, y);
+                var u = _(x, y - 1) > _(x, y);
+                var d = _(x, y + 1) > _(x, y);
+
+                return l || r || u || d;
+            }
+        }
+
+        private int[][] Parse(string v)
+        {
+            return v.Split(new[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries)
+                .Where(x => !string.IsNullOrEmpty(x))
+                .Select(x =>
+            {
+                return x.Split(' ').Select(s => int.Parse(s)).ToArray();
+            }).ToArray();
+        }
     }

     public class MasterMethod<T>


Improved exception error message when opcode is not implemented.

--- src/SharpLang.Compiler/Compiler.cs
+++ src/SharpLang.Compiler/Compiler.cs
@@ -325,7 +325,7 @@
                         break;
                     }
                     default:
-                        throw new NotImplementedException("Opcode not implemented.");
+                        throw new NotImplementedException(string.Format("Opcode {0} not implemented.", instruction.OpCode));
                 }
             }
         }


Fixed a small bug in the UpgradeForm: backup folder was not passed from UI to the command line tool

--- src/SubtextUpgrader/UpgradeForm.cs
+++ src/SubtextUpgrader/UpgradeForm.cs
@@ -43,7 +43,7 @@
 				return;
 			}

-			var backupDirectory = (string.IsNullOrEmpty(this.textBox3.Text)) ? this.textBox3.Text : string.Empty;
+		    var backupDirectory = (string.IsNullOrEmpty(this.textBox3.Text)) ? string.Empty : this.textBox3.Text;

 			var settings = new Settings(
 				this.textBox1.Text,


Miss click

Miss click

--- src/Tests/Peachpie.Test/Program.cs
+++ src/Tests/Peachpie.Test/Program.cs
@@ -6,7 +6,7 @@
 {
     public class Program
     {
-        const string ScriptPath = @"crypt_002.php";
+        const string ScriptPath = "index.php";

         static void Main(string[] args)
         {
@@ -36,4 +36,4 @@
             }
         }
     }
-}+}


Fixed issue #220, making Get public

Fixed issue #220, making Get public

--- src/Topshelf/Logging/HostLogger.cs
+++ src/Topshelf/Logging/HostLogger.cs
@@ -55,7 +55,7 @@
             return Get(type.GetTypeName());
         }

-        static LogWriter Get(string name)
+        public static LogWriter Get(string name)
         {
             return Current.Get(name);
         }


Fixes ProjectionVersion comparison

Fixes ProjectionVersion comparison

--- src/Elders.Cronus/Projections/ProjectionVersion.cs
+++ src/Elders.Cronus/Projections/ProjectionVersion.cs
@@ -6,6 +6,8 @@
     [DataContract(Name = "bb4883b9-c3a5-48e5-8ba1-28fb94d061ac")]
     public class ProjectionVersion : ValueObject<ProjectionVersion>
     {
+        ProjectionVersion() { }
+
         public ProjectionVersion(string projectionName, ProjectionStatus status, int revision, string hash)
         {
             ProjectionName = projectionName;
@@ -90,8 +92,10 @@

         public static bool operator >(ProjectionVersion left, ProjectionVersion right)
         {
-            if (ReferenceEquals(null, left)) throw new ArgumentNullException(nameof(left));
-            if (ReferenceEquals(null, right)) throw new ArgumentNullException(nameof(right));
+            if (left is null && right is null == false) return false;
+            if (left is null && right is null) return false;
+            if (left is null == false && right is null) return true;
+
             if (left.ProjectionName.Equals(right.ProjectionName) == false) throw new ArgumentException($"Unable to compare projection versions. ProjectionNames do not match. {left.ProjectionName} != {right.ProjectionName}");

             return left.Revision > right.Revision;
@@ -99,8 +103,10 @@

         public static bool operator >=(ProjectionVersion left, ProjectionVersion right)
         {
-            if (ReferenceEquals(null, left)) throw new ArgumentNullException(nameof(left));
-            if (ReferenceEquals(null, right)) throw new ArgumentNullException(nameof(right));
+            if (left is null && right is null == false) return false;
+            if (left is null && right is null) return true;
+            if (left is null == false && right is null) return true;
+
             if (left.ProjectionName.Equals(right.ProjectionName) == false) throw new ArgumentException($"Unable to compare projection versions. ProjectionNames do not match. {left.ProjectionName} != {right.ProjectionName}");

             return left.Revision >= right.Revision;
@@ -108,8 +114,10 @@

         public static bool operator <(ProjectionVersion left, ProjectionVersion right)
         {
-            if (ReferenceEquals(null, left)) throw new ArgumentNullException(nameof(left));
-            if (ReferenceEquals(null, right)) throw new ArgumentNullException(nameof(right));
+            if (left is null && right is null == false) return true;
+            if (left is null && right is null) return false;
+            if (left is null == false && right is null) return false;
+
             if (left.ProjectionName.Equals(right.ProjectionName) == false) throw new ArgumentException($"Unable to compare projection versions. ProjectionNames do not match. {left.ProjectionName} != {right.ProjectionName}");

             return left.Revision < right.Revision;
@@ -117,8 +125,10 @@

         public static bool operator <=(ProjectionVersion left, ProjectionVersion right)
         {
-            if (ReferenceEquals(null, left)) throw new ArgumentNullException(nameof(left));
-            if (ReferenceEquals(null, right)) throw new ArgumentNullException(nameof(right));
+            if (left is null && right is null == false) return true;
+            if (left is null && right is null) return true;
+            if (left is null == false && right is null) return false;
+
             if (left.ProjectionName.Equals(right.ProjectionName) == false) throw new ArgumentException($"Unable to compare projection versions. ProjectionNames do not match. {left.ProjectionName} != {right.ProjectionName}");

             return left.Revision <= right.Revision;


Remove unnecessary source file

Remove unnecessary source file

--- src/UserInputMacro/AsyncCommand.cs
+++ src/UserInputMacro/AsyncCommand.cs
@@ -1,46 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading;
-using System.Threading.Tasks;
-using System.Windows.Input;
-using System.ComponentModel;
-
-namespace UserInputMacro
-{
-	class AsyncCommand : ICommand
-	{
-		private Func<Task> execute;
-		private Func<bool> canExecute;
-		private CancellationTokenSource cancelSrc;
-
-		public AsyncCommand( Func<Task> executeTask, Func<bool> canExecuteFunc )
-		{
-			execute = executeTask;
-			canExecute = canExecuteFunc;
-		}
-
-		event EventHandler ICommand.CanExecuteChanged
-		{
-			add { CommandManager.RequerySuggested += value; }
-			remove { CommandManager.RequerySuggested -= value; }
-		}
-
-		public bool CanExecute( object parameter )
-		{
-			return canExecute();
-		}
-
-		public async void Execute( object parameter )
-		{
-			cancelSrc = new CancellationTokenSource();
-			await execute();
-		}
-
-		public void Cancel()
-		{
-			cancelSrc?.Cancel();
-		}
-	}
-}


Hex infill was not always starting at a low enough y.

--- infill.cs
+++ infill.cs
@@ -192,7 +192,7 @@
 					AABB boundary = new AABB(outlines);

 					boundary.min.X = ((boundary.min.X / lineSpacing) - 1) * lineSpacing;
-					boundary.min.Y = ((boundary.min.Y / perIncrementOffset) - 1) * perIncrementOffset;
+					boundary.min.Y = ((boundary.min.Y / perIncrementOffset) - 2) * perIncrementOffset;
 					boundary.max.X += lineSpacing;
 					boundary.max.Y += perIncrementOffset;
 					Polygons unclipedPatern = new Polygons();


Fix slot to correctly display in reports (#1847)

--- src/JoinRpg.WebPortal.Models/Characters/CharacterGroupReportViewModel.cs
+++ src/JoinRpg.WebPortal.Models/Characters/CharacterGroupReportViewModel.cs
@@ -1,6 +1,7 @@
 using JetBrains.Annotations;
 using JoinRpg.DataModel;
 using JoinRpg.Helpers;
+using JoinRpg.PrimitiveTypes;

 namespace JoinRpg.Web.Models.Characters;

@@ -52,14 +53,12 @@
             var flatCharacters = flatChilds.SelectMany(c => c.Characters).Where(c => c.IsActive)
                 .Distinct().ToList();

-            vm.TotalSlots = flatChilds.Sum(c =>
-                                c.AvaiableDirectSlots == -1 ? 0 : c.AvaiableDirectSlots) +
-                            flatCharacters.Count(c => c.IsAvailable);
+            vm.TotalSlots = CountSlotsForGroups(flatChilds) + CountSlotsForCharacters(flatCharacters);

-            vm.TotalCharacters = flatCharacters.Count + flatChilds.Sum(c =>
-                                     c.AvaiableDirectSlots == -1 ? 0 : c.AvaiableDirectSlots);
+            vm.TotalCharacters = flatCharacters.Sum(x => CharacterSlotCount(x))
+                + CountSlotsForGroups(flatChilds);
             vm.TotalNpcCharacters =
-                flatCharacters.Count(c => !c.IsAcceptingClaims && c.ApprovedClaim == null);
+                flatCharacters.Count(c => c.CharacterType == PrimitiveTypes.CharacterType.NonPlayer);
             vm.TotalCharactersWithPlayers = flatCharacters.Count(c => c.ApprovedClaim != null);
             vm.TotalInGameCharacters = flatCharacters.Count(c => c.InGame);

@@ -75,7 +74,21 @@
             vm.TotalCheckedInClaims =
                 flatCharacters.Count(c => c.ApprovedClaim?.CheckInDate != null);
             vm.Unlimited = vm.AvaiableDirectSlots == -1 ||
-                           flatChilds.Any(c => c.AvaiableDirectSlots == -1);
+                           flatChilds.Any(c => c.AvaiableDirectSlots == -1) || flatCharacters.Any(c => c.CharacterType == PrimitiveTypes.CharacterType.Slot && c.CharacterSlotLimit is null);
         }
+
+        private static int CountSlotsForCharacters(List<Character> flatCharacters) => flatCharacters.Sum(c => CharacterSlotCount(c));
+        private static int CountSlotsForGroups(List<CharacterGroup> flatChilds) => flatChilds.Sum(c => GroupSlotCount(c));
+        private static int CharacterSlotCount(Character c) =>
+            (c.CharacterType, c.ApprovedClaim) switch
+            {
+                (_, not null) => 0,
+                (CharacterType.Slot, null) => c.CharacterSlotLimit ?? 0,
+                (CharacterType.NonPlayer, null) => 0,
+                (CharacterType.Player, null) => 1,
+                _ => throw new InvalidOperationException(),
+            };
+
+        private static int GroupSlotCount(CharacterGroup c) => c.AvaiableDirectSlots == -1 ? 0 : c.AvaiableDirectSlots;
     }
 }


1500.3: TopWindowEventRoot

1500.3: TopWindowEventRoot

--- src/PixelFarm/PaintLab.YourImplementation/1_Events/TopWindowEventRoot.cs
+++ src/PixelFarm/PaintLab.YourImplementation/1_Events/TopWindowEventRoot.cs
@@ -170,7 +170,7 @@
             }

-            _localMouseDownX = this._localMouseDownY = 0;
+            _localMouseDownX = _localMouseDownY = 0;
             _mouseCursorStyle = e.MouseCursorStyle;
             ReleaseMouseEvent(e);


Add clear exception message, remove not null check (#984)

--- src/Quartz.Extensions.DependencyInjection/ServiceCollectionExtensions.cs
+++ src/Quartz.Extensions.DependencyInjection/ServiceCollectionExtensions.cs
@@ -35,11 +35,14 @@
             services.AddOptions();
             services.TryAddSingleton<MicrosoftLoggingProvider?>(serviceProvider =>
             {
-                var loggerFactory = serviceProvider.GetRequiredService<ILoggerFactory>();
-                if (loggerFactory != null)
+                var loggerFactory = serviceProvider.GetService<ILoggerFactory>();
+
+                if (loggerFactory is null)
                 {
-                    LogContext.SetCurrentLogProvider(loggerFactory);
+                    throw new InvalidOperationException($"{nameof(ILoggerFactory)} service is required");
                 }
+
+                LogContext.SetCurrentLogProvider(loggerFactory);

                 return LogProvider.CurrentLogProvider as MicrosoftLoggingProvider;
             });


Add tests

Add tests

--- src/Roslyn.Diagnostics.Analyzers/UnitTests/BlankLines/BlankLinesTests.cs
+++ src/Roslyn.Diagnostics.Analyzers/UnitTests/BlankLines/BlankLinesTests.cs
@@ -18,7 +18,7 @@
     public class BlankLinesTests
     {
         [Fact]
-        public async Task TestSingleBlankLineAtTopOfFile()
+        public async Task TestOneBlankLineAtTopOfFile()
         {
             var code =
 @"
@@ -87,5 +87,76 @@
                 FixedCode = fixedCode,
             }.RunAsync();
         }
+
+        [Fact]
+        public async Task TestOneBlankLineAtTopOfEmptyFile()
+        {
+            var code =
+@"
+";
+
+            await new VerifyCS.Test()
+            {
+                TestCode = code,
+                FixedCode = code,
+            }.RunAsync();
+        }
+
+        [Fact]
+        public async Task TestTwoBlankLinesAtTopOfEmptyFile()
+        {
+            var code =
+@"[||]
+
+";
+            var fixedCode =
+@"
+";
+
+            await new VerifyCS.Test()
+            {
+                TestCode = code,
+                FixedCode = fixedCode,
+            }.RunAsync();
+        }
+
+        [Fact]
+        public async Task TestThreeBlankLinesAtTopOfEmptyFile()
+        {
+            var code =
+@"[||]
+
+
+";
+            var fixedCode =
+@"
+";
+
+            await new VerifyCS.Test()
+            {
+                TestCode = code,
+                FixedCode = fixedCode,
+            }.RunAsync();
+        }
+
+        [Fact]
+        public async Task TestFourBlankLinesAtTopOfEmptyFile()
+        {
+            var code =
+@"[||]
+
+
+
+";
+            var fixedCode =
+@"
+";
+
+            await new VerifyCS.Test()
+            {
+                TestCode = code,
+                FixedCode = fixedCode,
+            }.RunAsync();
+        }
     }
 }


fix(homepage genric featured item): 366 JonH/Colin - Removes id's from items that don't required them and were causing duplicatesg

--- src/StockportWebapp/Views/stockportgov/Shared/GenericFeaturedItem.cshtml
+++ src/StockportWebapp/Views/stockportgov/Shared/GenericFeaturedItem.cshtml
@@ -7,7 +7,7 @@

 4 ? "hide-on-mobile" : string.Empty)">

-
+

@@ -20,7 +20,7 @@
                         @foreach (var subItem in item.SubItems.Take(2))
                         {

-                            @subItem.Title
+                            @subItem.Title
                         }

                     }


chore(Group donations): Change 'Get in touch with us' to 'Make a donation'

--- src/StockportWebapp/Views/stockportgov/Shared/Groups/DonationsBar.cshtml
+++ src/StockportWebapp/Views/stockportgov/Shared/Groups/DonationsBar.cshtml
@@ -16,11 +16,11 @@
             }
             @if (string.IsNullOrEmpty(Model.DonationsUrl))
             {
-                <stock-button class="volunteering-btn" as-link="true" target="_blank" href="mailto:@Model.Email?subject=Donations&body=Hello%0A%0AI%20am%20interested%20in%20making%20a%20donation.%20%20I%20found%20your%20details%20here:%20https://www.stockport.gov.uk/@Model.Url%0A%0AI%20would%20be%20grateful%20if%20you%20could%20contact%20me%20to%20explain%20how%20I%20can%20make%20a%20donation.%0A%0AName:%0A%0AEmail:%0A%0ATelephone%20Number:%0A%0AI%20look%20forward%20to%20hearing%20from%20you.">Get in touch with us</stock-Button>
+                <stock-button class="volunteering-btn" as-link="true" target="_blank" href="mailto:@Model.Email?subject=Donations&body=Hello%0A%0AI%20am%20interested%20in%20making%20a%20donation.%20%20I%20found%20your%20details%20here:%20https://www.stockport.gov.uk/@Model.Url%0A%0AI%20would%20be%20grateful%20if%20you%20could%20contact%20me%20to%20explain%20how%20I%20can%20make%20a%20donation.%0A%0AName:%0A%0AEmail:%0A%0ATelephone%20Number:%0A%0AI%20look%20forward%20to%20hearing%20from%20you.">Make a donation</stock-Button>
             }
             else
             {
-                <stock-button class="volunteering-btn" as-link="true" target="_blank" href="@Model.DonationsUrl">Make a Donation</stock-button>
+                <stock-button class="volunteering-btn" as-link="true" target="_blank" href="@Model.DonationsUrl">Make a donation</stock-button>
             }

         </div>