/// <summary>Creates a new binary buffer, initialized by copying pre-existing data</summary>
        /// <param name="prefix">Data that will be copied at the start of the buffer</param>
        /// <param name="capacity">Optional initial capacity of the buffer</param>
        /// <remarks>The cursor will already be placed at the end of the prefix</remarks>
        public SliceWriter(Slice prefix, int capacity = 0)
        {
            if (capacity < 0)
            {
                throw new ArgumentException("Capacity must be a positive integer.", "capacity");
            }

            int n = prefix.Count;

            Contract.Assert(n >= 0);

            if (capacity == 0)
            {             // most frequent usage is to add a packed integer at the end of a prefix
                capacity = SliceHelpers.Align(n + 8);
            }
            else
            {
                capacity = Math.Max(capacity, n);
            }

            var buffer = new byte[capacity];

            if (n > 0)
            {
                prefix.CopyTo(buffer, 0);
            }

            this.Buffer   = buffer;
            this.Position = n;
        }
        /// <summary>Resize a buffer by doubling its capacity</summary>
        /// <param name="buffer">Reference to the variable holding the buffer to create/resize. If null, a new buffer will be allocated. If not, the content of the buffer will be copied into the new buffer.</param>
        /// <param name="minimumCapacity">Mininum guaranteed buffer size after resizing.</param>
        /// <remarks>The buffer will be resized to the maximum betweeb the previous size multiplied by 2, and <paramref name="minimumCapacity"/>. The capacity will always be rounded to a multiple of 16 to reduce memory fragmentation</remarks>
        public static void GrowBuffer(ref byte[] buffer, int minimumCapacity = 0)
        {
            Contract.Requires(minimumCapacity >= 0);

            // double the size of the buffer, or use the minimum required
            long newSize = Math.Max(buffer == null ? 0 : (((long)buffer.Length) << 1), minimumCapacity);

            // .NET (as of 4.5) cannot allocate an array with more than 2^31 - 1 items...
            if (newSize > 0x7fffffffL)
            {
                FailCannotGrowBuffer();
            }

            // round up to 16 bytes, to reduce fragmentation
            int size = SliceHelpers.Align((int)newSize);

            Array.Resize(ref buffer, size);
        }