From 263d085885df024dca9250cc03c807912b0a7662 Mon Sep 17 00:00:00 2001
From: Matthew Swift <matthew.swift@forgerock.com>
Date: Tue, 24 Apr 2012 22:33:21 +0000
Subject: [PATCH] Reformat to comply with new Checkstyle rules.

---
 opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/ByteStringBuilder.java | 1990 +++++++++++++++++++++++++--------------------------------
 1 files changed, 874 insertions(+), 1,116 deletions(-)

diff --git a/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/ByteStringBuilder.java b/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/ByteStringBuilder.java
index f709bf3..6ecfd05 100755
--- a/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/ByteStringBuilder.java
+++ b/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/ByteStringBuilder.java
@@ -6,17 +6,16 @@
  * (the "License").  You may not use this file except in compliance
  * with the License.
  *
- * You can obtain a copy of the license at
- * trunk/opendj3/legal-notices/CDDLv1_0.txt
+ * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt
  * or http://forgerock.org/license/CDDLv1.0.html.
  * See the License for the specific language governing permissions
  * and limitations under the License.
  *
  * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at
- * trunk/opendj3/legal-notices/CDDLv1_0.txt.  If applicable,
- * add the following below this CDDL HEADER, with the fields enclosed
- * by brackets "[]" replaced with your own identifying information:
+ * file and include the License file at legal-notices/CDDLv1_0.txt.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information:
  *      Portions Copyright [yyyy] [name of copyright owner]
  *
  * CDDL HEADER END
@@ -27,8 +26,6 @@
  */
 package org.forgerock.opendj.ldap;
 
-
-
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
@@ -39,1146 +36,907 @@
 
 import com.forgerock.opendj.util.StaticUtils;
 
-
-
 /**
  * A mutable sequence of bytes backed by a byte array.
  */
-public final class ByteStringBuilder implements ByteSequence
-{
-
-  /**
-   * A sub-sequence of the parent byte string builder. The sub-sequence will be
-   * robust against all updates to the byte string builder except for
-   * invocations of the method {@code clear()}.
-   */
-  private final class SubSequence implements ByteSequence
-  {
-
-    // The length of the sub-sequence.
-    private final int subLength;
-
-    // The offset of the sub-sequence.
-    private final int subOffset;
-
-
+public final class ByteStringBuilder implements ByteSequence {
 
     /**
-     * Creates a new sub-sequence.
+     * A sub-sequence of the parent byte string builder. The sub-sequence will
+     * be robust against all updates to the byte string builder except for
+     * invocations of the method {@code clear()}.
+     */
+    private final class SubSequence implements ByteSequence {
+
+        // The length of the sub-sequence.
+        private final int subLength;
+
+        // The offset of the sub-sequence.
+        private final int subOffset;
+
+        /**
+         * Creates a new sub-sequence.
+         *
+         * @param offset
+         *            The offset of the sub-sequence.
+         * @param length
+         *            The length of the sub-sequence.
+         */
+        private SubSequence(final int offset, final int length) {
+            this.subOffset = offset;
+            this.subLength = length;
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public ByteSequenceReader asReader() {
+            return new ByteSequenceReader(this);
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public byte byteAt(final int index) {
+            if (index >= subLength || index < 0) {
+                throw new IndexOutOfBoundsException();
+            }
+
+            // Protect against reallocation: use builder's buffer.
+            return buffer[subOffset + index];
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public int compareTo(final byte[] b, final int offset, final int length) {
+            ByteString.checkArrayBounds(b, offset, length);
+
+            // Protect against reallocation: use builder's buffer.
+            return ByteString.compareTo(buffer, subOffset, subLength, b, offset, length);
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public int compareTo(final ByteSequence o) {
+            if (this == o) {
+                return 0;
+            }
+
+            // Protect against reallocation: use builder's buffer.
+            return -o.compareTo(buffer, subOffset, subLength);
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public byte[] copyTo(final byte[] b) {
+            copyTo(b, 0);
+            return b;
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public byte[] copyTo(final byte[] b, final int offset) {
+            if (offset < 0) {
+                throw new IndexOutOfBoundsException();
+            }
+
+            // Protect against reallocation: use builder's buffer.
+            System.arraycopy(buffer, subOffset, b, offset, Math.min(subLength, b.length - offset));
+            return b;
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public ByteStringBuilder copyTo(final ByteStringBuilder builder) {
+            // Protect against reallocation: use builder's buffer.
+            return builder.append(buffer, subOffset, subLength);
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public OutputStream copyTo(final OutputStream stream) throws IOException {
+            // Protect against reallocation: use builder's buffer.
+            stream.write(buffer, subOffset, subLength);
+            return stream;
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public boolean equals(final byte[] b, final int offset, final int length) {
+            ByteString.checkArrayBounds(b, offset, length);
+
+            // Protect against reallocation: use builder's buffer.
+            return ByteString.equals(buffer, subOffset, subLength, b, offset, length);
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public boolean equals(final Object o) {
+            if (this == o) {
+                return true;
+            } else if (o instanceof ByteSequence) {
+                final ByteSequence other = (ByteSequence) o;
+
+                // Protect against reallocation: use builder's buffer.
+                return other.equals(buffer, subOffset, subLength);
+            } else {
+                return false;
+            }
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public int hashCode() {
+            // Protect against reallocation: use builder's buffer.
+            return ByteString.hashCode(buffer, subOffset, subLength);
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public int length() {
+            return subLength;
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public ByteSequence subSequence(final int start, final int end) {
+            if (start < 0 || start > end || end > subLength) {
+                throw new IndexOutOfBoundsException();
+            }
+
+            return new SubSequence(subOffset + start, end - start);
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public byte[] toByteArray() {
+            return copyTo(new byte[subLength]);
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public ByteString toByteString() {
+            // Protect against reallocation: use builder's buffer.
+            final byte[] b = new byte[subLength];
+            System.arraycopy(buffer, subOffset, b, 0, subLength);
+            return ByteString.wrap(b);
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public String toString() {
+            // Protect against reallocation: use builder's buffer.
+            return ByteString.toString(buffer, subOffset, subLength);
+        }
+    }
+
+    // These are package private so that compression and crypto
+    // functionality may directly access the fields.
+
+    // The buffer where data is stored.
+    byte[] buffer;
+
+    // The number of bytes to expose from the buffer.
+    int length;
+
+    /**
+     * Creates a new byte string builder with an initial capacity of 32 bytes.
+     */
+    public ByteStringBuilder() {
+        // Initially create a 32 byte buffer.
+        this(32);
+    }
+
+    /**
+     * Creates a new byte string builder with the specified initial capacity.
      *
-     * @param offset
-     *          The offset of the sub-sequence.
-     * @param length
-     *          The length of the sub-sequence.
+     * @param capacity
+     *            The initial capacity.
+     * @throws IllegalArgumentException
+     *             If the {@code capacity} is negative.
      */
-    private SubSequence(final int offset, final int length)
-    {
-      this.subOffset = offset;
-      this.subLength = length;
+    public ByteStringBuilder(final int capacity) {
+        if (capacity < 0) {
+            throw new IllegalArgumentException();
+        }
+
+        this.buffer = new byte[capacity];
+        this.length = 0;
     }
 
-
-
     /**
-     * {@inheritDoc}
+     * Appends the provided byte to this byte string builder.
+     *
+     * @param b
+     *            The byte to be appended to this byte string builder.
+     * @return This byte string builder.
      */
-    public ByteSequenceReader asReader()
-    {
-      return new ByteSequenceReader(this);
-    }
-
-
-
-    /**
-     * {@inheritDoc}
-     */
-    public byte byteAt(final int index)
-    {
-      if (index >= subLength || index < 0)
-      {
-        throw new IndexOutOfBoundsException();
-      }
-
-      // Protect against reallocation: use builder's buffer.
-      return buffer[subOffset + index];
-    }
-
-
-
-    /**
-     * {@inheritDoc}
-     */
-    public int compareTo(final byte[] b, final int offset, final int length)
-    {
-      ByteString.checkArrayBounds(b, offset, length);
-
-      // Protect against reallocation: use builder's buffer.
-      return ByteString.compareTo(buffer, subOffset, subLength, b, offset,
-          length);
-    }
-
-
-
-    /**
-     * {@inheritDoc}
-     */
-    public int compareTo(final ByteSequence o)
-    {
-      if (this == o)
-      {
-        return 0;
-      }
-
-      // Protect against reallocation: use builder's buffer.
-      return -o.compareTo(buffer, subOffset, subLength);
-    }
-
-
-
-    /**
-     * {@inheritDoc}
-     */
-    public byte[] copyTo(final byte[] b)
-    {
-      copyTo(b, 0);
-      return b;
-    }
-
-
-
-    /**
-     * {@inheritDoc}
-     */
-    public byte[] copyTo(final byte[] b, final int offset)
-    {
-      if (offset < 0)
-      {
-        throw new IndexOutOfBoundsException();
-      }
-
-      // Protect against reallocation: use builder's buffer.
-      System.arraycopy(buffer, subOffset, b, offset, Math.min(subLength,
-          b.length - offset));
-      return b;
-    }
-
-
-
-    /**
-     * {@inheritDoc}
-     */
-    public ByteStringBuilder copyTo(final ByteStringBuilder builder)
-    {
-      // Protect against reallocation: use builder's buffer.
-      return builder.append(buffer, subOffset, subLength);
-    }
-
-
-
-    /**
-     * {@inheritDoc}
-     */
-    public OutputStream copyTo(final OutputStream stream) throws IOException
-    {
-      // Protect against reallocation: use builder's buffer.
-      stream.write(buffer, subOffset, subLength);
-      return stream;
-    }
-
-
-
-    /**
-     * {@inheritDoc}
-     */
-    public boolean equals(final byte[] b, final int offset, final int length)
-    {
-      ByteString.checkArrayBounds(b, offset, length);
-
-      // Protect against reallocation: use builder's buffer.
-      return ByteString.equals(buffer, subOffset, subLength, b, offset, length);
-    }
-
-
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public boolean equals(final Object o)
-    {
-      if (this == o)
-      {
-        return true;
-      }
-      else if (o instanceof ByteSequence)
-      {
-        final ByteSequence other = (ByteSequence) o;
-
-        // Protect against reallocation: use builder's buffer.
-        return other.equals(buffer, subOffset, subLength);
-      }
-      else
-      {
-        return false;
-      }
-    }
-
-
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public int hashCode()
-    {
-      // Protect against reallocation: use builder's buffer.
-      return ByteString.hashCode(buffer, subOffset, subLength);
-    }
-
-
-
-    /**
-     * {@inheritDoc}
-     */
-    public int length()
-    {
-      return subLength;
-    }
-
-
-
-    /**
-     * {@inheritDoc}
-     */
-    public ByteSequence subSequence(final int start, final int end)
-    {
-      if (start < 0 || start > end || end > subLength)
-      {
-        throw new IndexOutOfBoundsException();
-      }
-
-      return new SubSequence(subOffset + start, end - start);
-    }
-
-
-
-    /**
-     * {@inheritDoc}
-     */
-    public byte[] toByteArray()
-    {
-      return copyTo(new byte[subLength]);
-    }
-
-
-
-    /**
-     * {@inheritDoc}
-     */
-    public ByteString toByteString()
-    {
-      // Protect against reallocation: use builder's buffer.
-      final byte[] b = new byte[subLength];
-      System.arraycopy(buffer, subOffset, b, 0, subLength);
-      return ByteString.wrap(b);
-    }
-
-
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public String toString()
-    {
-      // Protect against reallocation: use builder's buffer.
-      return ByteString.toString(buffer, subOffset, subLength);
-    }
-  }
-
-
-
-  // These are package private so that compression and crypto
-  // functionality may directly access the fields.
-
-  // The buffer where data is stored.
-  byte[] buffer;
-
-  // The number of bytes to expose from the buffer.
-  int length;
-
-
-
-  /**
-   * Creates a new byte string builder with an initial capacity of 32 bytes.
-   */
-  public ByteStringBuilder()
-  {
-    // Initially create a 32 byte buffer.
-    this(32);
-  }
-
-
-
-  /**
-   * Creates a new byte string builder with the specified initial capacity.
-   *
-   * @param capacity
-   *          The initial capacity.
-   * @throws IllegalArgumentException
-   *           If the {@code capacity} is negative.
-   */
-  public ByteStringBuilder(final int capacity)
-  {
-    if (capacity < 0)
-    {
-      throw new IllegalArgumentException();
-    }
-
-    this.buffer = new byte[capacity];
-    this.length = 0;
-  }
-
-
-
-  /**
-   * Appends the provided byte to this byte string builder.
-   *
-   * @param b
-   *          The byte to be appended to this byte string builder.
-   * @return This byte string builder.
-   */
-  public ByteStringBuilder append(final byte b)
-  {
-    ensureAdditionalCapacity(1);
-    buffer[length++] = b;
-    return this;
-  }
-
-
-
-  /**
-   * Appends the provided byte array to this byte string builder.
-   * <p>
-   * An invocation of the form:
-   *
-   * <pre>
-   * src.append(bytes)
-   * </pre>
-   *
-   * Behaves in exactly the same way as the invocation:
-   *
-   * <pre>
-   * src.append(bytes, 0, bytes.length);
-   * </pre>
-   *
-   * @param bytes
-   *          The byte array to be appended to this byte string builder.
-   * @return This byte string builder.
-   */
-  public ByteStringBuilder append(final byte[] bytes)
-  {
-    return append(bytes, 0, bytes.length);
-  }
-
-
-
-  /**
-   * Appends the provided byte array to this byte string builder.
-   *
-   * @param bytes
-   *          The byte array to be appended to this byte string builder.
-   * @param offset
-   *          The offset of the byte array to be used; must be non-negative and
-   *          no larger than {@code bytes.length} .
-   * @param length
-   *          The length of the byte array to be used; must be non-negative and
-   *          no larger than {@code bytes.length - offset}.
-   * @return This byte string builder.
-   * @throws IndexOutOfBoundsException
-   *           If {@code offset} is negative or if {@code length} is negative or
-   *           if {@code offset + length} is greater than {@code bytes.length}.
-   */
-  public ByteStringBuilder append(final byte[] bytes, final int offset,
-      final int length)
-  {
-    ByteString.checkArrayBounds(bytes, offset, length);
-
-    if (length != 0)
-    {
-      ensureAdditionalCapacity(length);
-      System.arraycopy(bytes, offset, buffer, this.length, length);
-      this.length += length;
-    }
-
-    return this;
-  }
-
-
-
-  /**
-   * Appends the provided {@code ByteBuffer} to this byte string builder.
-   *
-   * @param buffer
-   *          The byte buffer to be appended to this byte string builder.
-   * @param length
-   *          The number of bytes to be appended from {@code buffer}.
-   * @return This byte string builder.
-   * @throws IndexOutOfBoundsException
-   *           If {@code length} is less than zero or greater than {@code
-   *           buffer.remaining()}.
-   */
-  public ByteStringBuilder append(final ByteBuffer buffer, final int length)
-  {
-    if (length < 0 || length > buffer.remaining())
-    {
-      throw new IndexOutOfBoundsException();
-    }
-
-    if (length != 0)
-    {
-      ensureAdditionalCapacity(length);
-      buffer.get(this.buffer, this.length, length);
-      this.length += length;
-    }
-
-    return this;
-  }
-
-
-
-  /**
-   * Appends the provided {@link ByteSequence} to this byte string builder.
-   *
-   * @param bytes
-   *          The byte sequence to be appended to this byte string builder.
-   * @return This byte string builder.
-   */
-  public ByteStringBuilder append(final ByteSequence bytes)
-  {
-    return bytes.copyTo(this);
-  }
-
-
-
-  /**
-   * Appends the provided {@link ByteSequenceReader} to this byte string
-   * builder.
-   *
-   * @param reader
-   *          The byte sequence reader to be appended to this byte string
-   *          builder.
-   * @param length
-   *          The number of bytes to be appended from {@code reader}.
-   * @return This byte string builder.
-   * @throws IndexOutOfBoundsException
-   *           If {@code length} is less than zero or greater than {@code
-   *           reader.remaining()}.
-   */
-  public ByteStringBuilder append(final ByteSequenceReader reader,
-      final int length)
-  {
-    if (length < 0 || length > reader.remaining())
-    {
-      throw new IndexOutOfBoundsException();
-    }
-
-    if (length != 0)
-    {
-      ensureAdditionalCapacity(length);
-      reader.get(buffer, this.length, length);
-      this.length += length;
-    }
-
-    return this;
-  }
-
-
-
-  /**
-   * Appends the UTF-8 encoded bytes of the provided
-   * char array to this byte string
-   * builder.
-   *
-   * @param chars
-   *          The char array whose UTF-8 encoding is to be appended to this byte
-   *          string builder.
-   * @return This byte string builder.
-   */
-  public ByteStringBuilder append(final char[] chars)
-  {
-    if (chars == null)
-    {
-      return this;
-    }
-
-    // Assume that each char is 1 byte
-    final int len = chars.length;
-    ensureAdditionalCapacity(len);
-
-    for (int i = 0; i < len; i++)
-    {
-      final char c = chars[i];
-      final byte b = (byte) (c & 0x0000007F);
-
-      if (c == b)
-      {
-        buffer[this.length + i] = b;
-      }
-      else
-      {
-        // There is a multi-byte char. Defer to JDK.
-        final Charset utf8 = Charset.forName("UTF-8");
-        final ByteBuffer byteBuffer = utf8.encode(CharBuffer.wrap(chars));
-        final int remaining = byteBuffer.remaining();
-        ensureAdditionalCapacity(remaining - len);
-        byteBuffer.get(buffer, this.length, remaining);
-        this.length += remaining;
+    public ByteStringBuilder append(final byte b) {
+        ensureAdditionalCapacity(1);
+        buffer[length++] = b;
         return this;
-      }
     }
 
-    // The 1 byte char assumption was correct
-    this.length += len;
-    return this;
-
-  }
-
-
-
-  /**
-   * Appends the provided {@code InputStream} to this byte string builder.
-   *
-   * @param stream
-   *          The input stream to be appended to this byte string builder.
-   * @param length
-   *          The maximum number of bytes to be appended from {@code buffer}.
-   * @return The number of bytes read from the input stream, or {@code -1} if
-   *         the end of the input stream has been reached.
-   * @throws IndexOutOfBoundsException
-   *           If {@code length} is less than zero.
-   * @throws IOException
-   *           If an I/O error occurs.
-   */
-  public int append(final InputStream stream, final int length)
-      throws IOException
-  {
-    if (length < 0)
-    {
-      throw new IndexOutOfBoundsException();
+    /**
+     * Appends the provided byte array to this byte string builder.
+     * <p>
+     * An invocation of the form:
+     *
+     * <pre>
+     * src.append(bytes)
+     * </pre>
+     *
+     * Behaves in exactly the same way as the invocation:
+     *
+     * <pre>
+     * src.append(bytes, 0, bytes.length);
+     * </pre>
+     *
+     * @param bytes
+     *            The byte array to be appended to this byte string builder.
+     * @return This byte string builder.
+     */
+    public ByteStringBuilder append(final byte[] bytes) {
+        return append(bytes, 0, bytes.length);
     }
 
-    ensureAdditionalCapacity(length);
-    final int bytesRead = stream.read(buffer, this.length, length);
-    if (bytesRead > 0)
-    {
-      this.length += bytesRead;
-    }
+    /**
+     * Appends the provided byte array to this byte string builder.
+     *
+     * @param bytes
+     *            The byte array to be appended to this byte string builder.
+     * @param offset
+     *            The offset of the byte array to be used; must be non-negative
+     *            and no larger than {@code bytes.length} .
+     * @param length
+     *            The length of the byte array to be used; must be non-negative
+     *            and no larger than {@code bytes.length - offset}.
+     * @return This byte string builder.
+     * @throws IndexOutOfBoundsException
+     *             If {@code offset} is negative or if {@code length} is
+     *             negative or if {@code offset + length} is greater than
+     *             {@code bytes.length}.
+     */
+    public ByteStringBuilder append(final byte[] bytes, final int offset, final int length) {
+        ByteString.checkArrayBounds(bytes, offset, length);
 
-    return bytesRead;
-  }
-
-
-
-  /**
-   * Appends the big-endian encoded bytes of the provided integer to this byte
-   * string builder.
-   *
-   * @param i
-   *          The integer whose big-endian encoding is to be appended to this
-   *          byte string builder.
-   * @return This byte string builder.
-   */
-  public ByteStringBuilder append(int i)
-  {
-    ensureAdditionalCapacity(4);
-    for (int j = length + 3; j >= length; j--)
-    {
-      buffer[j] = (byte) (i & 0xFF);
-      i >>>= 8;
-    }
-    length += 4;
-    return this;
-  }
-
-
-
-  /**
-   * Appends the big-endian encoded bytes of the provided long to this byte
-   * string builder.
-   *
-   * @param l
-   *          The long whose big-endian encoding is to be appended to this byte
-   *          string builder.
-   * @return This byte string builder.
-   */
-  public ByteStringBuilder append(long l)
-  {
-    ensureAdditionalCapacity(8);
-    for (int i = length + 7; i >= length; i--)
-    {
-      buffer[i] = (byte) (l & 0xFF);
-      l >>>= 8;
-    }
-    length += 8;
-    return this;
-  }
-
-
-
-  /**
-   * Appends the byte string representation of the provided object to this byte
-   * string builder. The object is converted to a byte string as follows:
-   * <ul>
-   * <li>if the object is an instance of {@code ByteSequence} then this method
-   * is equivalent to calling {@link #append(ByteSequence)}
-   * <li>if the object is a {@code byte[]} then this method is equivalent to
-   * calling {@link #append(byte[])}
-   * <li>if the object is a {@code char[]} then this method is equivalent to
-   * calling {@link #append(char[])}
-   * <li>for all other types of object this method is equivalent to calling
-   * {@link #append(String)} with the {@code toString()} representation of the
-   * provided object.
-   * </ul>
-   * <b>Note:</b> this method treats {@code Long} and {@code Integer} objects
-   * like any other type of {@code Object}. More specifically, the following
-   * invocations are not equivalent:
-   * <ul>
-   * <li>{@code append(0)} is not equivalent to {@code append((Object) 0)}
-   * <li>{@code append(0L)} is not equivalent to {@code append((Object) 0L)}
-   * </ul>
-   *
-   * @param o
-   *          The object to be appended to this byte string builder.
-   * @return This byte string builder.
-   */
-  public ByteStringBuilder append(final Object o)
-  {
-    if (o == null)
-    {
-      return this;
-    }
-    else if (o instanceof ByteSequence)
-    {
-      return append((ByteSequence) o);
-    }
-    else if (o instanceof byte[])
-    {
-      return append((byte[]) o);
-    }
-    else if (o instanceof char[])
-    {
-      return append((char[]) o);
-    }
-    else
-    {
-      return append(o.toString());
-    }
-  }
-
-
-
-  /**
-   * Appends the big-endian encoded bytes of the provided short to this byte
-   * string builder.
-   *
-   * @param i
-   *          The short whose big-endian encoding is to be appended to this byte
-   *          string builder.
-   * @return This byte string builder.
-   */
-  public ByteStringBuilder append(short i)
-  {
-    ensureAdditionalCapacity(2);
-    for (int j = length + 1; j >= length; j--)
-    {
-      buffer[j] = (byte) (i & 0xFF);
-      i >>>= 8;
-    }
-    length += 2;
-    return this;
-  }
-
-
-
-  /**
-   * Appends the UTF-8 encoded bytes of the provided string to this byte string
-   * builder.
-   *
-   * @param s
-   *          The string whose UTF-8 encoding is to be appended to this byte
-   *          string builder.
-   * @return This byte string builder.
-   */
-  public ByteStringBuilder append(final String s)
-  {
-    if (s == null)
-    {
-      return this;
-    }
-
-    // Assume that each char is 1 byte
-    final int len = s.length();
-    ensureAdditionalCapacity(len);
-
-    for (int i = 0; i < len; i++)
-    {
-      final char c = s.charAt(i);
-      final byte b = (byte) (c & 0x0000007F);
-
-      if (c == b)
-      {
-        buffer[this.length + i] = b;
-      }
-      else
-      {
-        // There is a multi-byte char. Defer to JDK
-        try
-        {
-          return append(s.getBytes("UTF-8"));
+        if (length != 0) {
+            ensureAdditionalCapacity(length);
+            System.arraycopy(bytes, offset, buffer, this.length, length);
+            this.length += length;
         }
-        catch (final Exception e)
-        {
-          if (StaticUtils.DEBUG_LOG.isLoggable(Level.WARNING))
-          {
-            StaticUtils.DEBUG_LOG.warning("Unable to encode String "
-                + "to UTF-8 bytes: " + e.toString());
-          }
 
-          return append(s.getBytes());
+        return this;
+    }
+
+    /**
+     * Appends the provided {@code ByteBuffer} to this byte string builder.
+     *
+     * @param buffer
+     *            The byte buffer to be appended to this byte string builder.
+     * @param length
+     *            The number of bytes to be appended from {@code buffer}.
+     * @return This byte string builder.
+     * @throws IndexOutOfBoundsException
+     *             If {@code length} is less than zero or greater than
+     *             {@code buffer.remaining()}.
+     */
+    public ByteStringBuilder append(final ByteBuffer buffer, final int length) {
+        if (length < 0 || length > buffer.remaining()) {
+            throw new IndexOutOfBoundsException();
         }
-      }
+
+        if (length != 0) {
+            ensureAdditionalCapacity(length);
+            buffer.get(this.buffer, this.length, length);
+            this.length += length;
+        }
+
+        return this;
     }
 
-    // The 1 byte char assumption was correct
-    this.length += len;
-    return this;
-  }
-
-
-
-  /**
-   * Appends the ASN.1 BER length encoding representation of the provided
-   * integer to this byte string builder.
-   *
-   * @param length
-   *          The value to encode using the BER length encoding rules.
-   * @return This byte string builder.
-   */
-  public ByteStringBuilder appendBERLength(final int length)
-  {
-    if ((length & 0x0000007F) == length)
-    {
-      ensureAdditionalCapacity(1);
-
-      buffer[this.length++] = (byte) (length & 0xFF);
-    }
-    else if ((length & 0x000000FF) == length)
-    {
-      ensureAdditionalCapacity(2);
-
-      buffer[this.length++] = (byte) 0x81;
-      buffer[this.length++] = (byte) (length & 0xFF);
-    }
-    else if ((length & 0x0000FFFF) == length)
-    {
-      ensureAdditionalCapacity(3);
-
-      buffer[this.length++] = (byte) 0x82;
-      buffer[this.length++] = (byte) (length >> 8 & 0xFF);
-      buffer[this.length++] = (byte) (length & 0xFF);
-    }
-    else if ((length & 0x00FFFFFF) == length)
-    {
-      ensureAdditionalCapacity(4);
-
-      buffer[this.length++] = (byte) 0x83;
-      buffer[this.length++] = (byte) (length >> 16 & 0xFF);
-      buffer[this.length++] = (byte) (length >> 8 & 0xFF);
-      buffer[this.length++] = (byte) (length & 0xFF);
-    }
-    else
-    {
-      ensureAdditionalCapacity(5);
-
-      buffer[this.length++] = (byte) 0x84;
-      buffer[this.length++] = (byte) (length >> 24 & 0xFF);
-      buffer[this.length++] = (byte) (length >> 16 & 0xFF);
-      buffer[this.length++] = (byte) (length >> 8 & 0xFF);
-      buffer[this.length++] = (byte) (length & 0xFF);
-    }
-    return this;
-  }
-
-
-
-  /**
-   * Returns a {@link ByteSequenceReader} which can be used to incrementally
-   * read and decode data from this byte string builder.
-   * <p>
-   * <b>NOTE:</b> all concurrent updates to this byte string builder are
-   * supported with the exception of {@link #clear()}. Any invocations of
-   * {@link #clear()} must be accompanied by a subsequent call to {@code
-   * ByteSequenceReader.rewind()}.
-   *
-   * @return The {@link ByteSequenceReader} which can be used to incrementally
-   *         read and decode data from this byte string builder.
-   * @see #clear()
-   */
-  public ByteSequenceReader asReader()
-  {
-    return new ByteSequenceReader(this);
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  public byte byteAt(final int index)
-  {
-    if (index >= length || index < 0)
-    {
-      throw new IndexOutOfBoundsException();
-    }
-    return buffer[index];
-  }
-
-
-
-  /**
-   * Sets the length of this byte string builder to zero.
-   * <p>
-   * <b>NOTE:</b> if this method is called, then {@code
-   * ByteSequenceReader.rewind()} must also be called on any associated byte
-   * sequence readers in order for them to remain valid.
-   *
-   * @return This byte string builder.
-   * @see #asReader()
-   */
-  public ByteStringBuilder clear()
-  {
-    length = 0;
-    return this;
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  public int compareTo(final byte[] bytes, final int offset, final int length)
-  {
-    ByteString.checkArrayBounds(bytes, offset, length);
-    return ByteString.compareTo(this.buffer, 0, this.length, bytes, offset,
-        length);
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  public int compareTo(final ByteSequence o)
-  {
-    if (this == o)
-    {
-      return 0;
-    }
-    return -o.compareTo(buffer, 0, length);
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  public byte[] copyTo(final byte[] bytes)
-  {
-    copyTo(bytes, 0);
-    return bytes;
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  public byte[] copyTo(final byte[] bytes, final int offset)
-  {
-    if (offset < 0)
-    {
-      throw new IndexOutOfBoundsException();
-    }
-    System.arraycopy(buffer, 0, bytes, offset,
-        Math.min(length, bytes.length - offset));
-    return bytes;
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  public ByteStringBuilder copyTo(final ByteStringBuilder builder)
-  {
-    builder.append(buffer, 0, length);
-    return builder;
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  public OutputStream copyTo(final OutputStream stream) throws IOException
-  {
-    stream.write(buffer, 0, length);
-    return stream;
-  }
-
-
-
-  /**
-   * Ensures that the specified number of additional bytes will fit in this byte
-   * string builder and resizes it if necessary.
-   *
-   * @param size
-   *          The number of additional bytes.
-   * @return This byte string builder.
-   */
-  public ByteStringBuilder ensureAdditionalCapacity(final int size)
-  {
-    final int newCount = this.length + size;
-    if (newCount > buffer.length)
-    {
-      final byte[] newbuffer = new byte[Math.max(buffer.length << 1, newCount)];
-      System.arraycopy(buffer, 0, newbuffer, 0, buffer.length);
-      buffer = newbuffer;
-    }
-    return this;
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  public boolean equals(final byte[] bytes, final int offset, final int length)
-  {
-    ByteString.checkArrayBounds(bytes, offset, length);
-    return ByteString
-        .equals(this.buffer, 0, this.length, bytes, offset, length);
-  }
-
-
-
-  /**
-   * Indicates whether the provided object is equal to this byte string builder.
-   * In order for it to be considered equal, the provided object must be a byte
-   * sequence containing the same bytes in the same order.
-   *
-   * @param o
-   *          The object for which to make the determination.
-   * @return {@code true} if the provided object is a byte sequence whose
-   *         content is equal to that of this byte string builder, or {@code
-   *         false} if not.
-   */
-  @Override
-  public boolean equals(final Object o)
-  {
-    if (this == o)
-    {
-      return true;
-    }
-    else if (o instanceof ByteSequence)
-    {
-      final ByteSequence other = (ByteSequence) o;
-      return other.equals(buffer, 0, length);
-    }
-    else
-    {
-      return false;
-    }
-  }
-
-
-
-  /**
-   * Returns the byte array that backs this byte string builder. Modifications
-   * to this byte string builder's content may cause the returned array's
-   * content to be modified, and vice versa.
-   * <p>
-   * Note that the length of the returned array is only guaranteed to be the
-   * same as the length of this byte string builder immediately after a call to
-   * {@link #trimToSize()}.
-   * <p>
-   * In addition, subsequent modifications to this byte string builder may cause
-   * the backing byte array to be reallocated thus decoupling the returned byte
-   * array from this byte string builder.
-   *
-   * @return The byte array that backs this byte string builder.
-   */
-  public byte[] getBackingArray()
-  {
-    return buffer;
-  }
-
-
-
-  /**
-   * Returns a hash code for this byte string builder. It will be the sum of all
-   * of the bytes contained in the byte string builder.
-   * <p>
-   * <b>NOTE:</b> subsequent changes to this byte string builder will invalidate
-   * the returned hash code.
-   *
-   * @return A hash code for this byte string builder.
-   */
-  @Override
-  public int hashCode()
-  {
-    return ByteString.hashCode(buffer, 0, length);
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  public int length()
-  {
-    return length;
-  }
-
-
-
-  /**
-   * Sets the length of this byte string builder.
-   * <p>
-   * If the <code>newLength</code> argument is less than the current length, the
-   * length is changed to the specified length.
-   * <p>
-   * If the <code>newLength</code> argument is greater than or equal to the
-   * current length, then the capacity is increased and sufficient null bytes
-   * are appended so that length becomes the <code>newLength</code> argument.
-   * <p>
-   * The <code>newLength</code> argument must be greater than or equal to
-   * <code>0</code>.
-   *
-   * @param newLength
-   *          The new length.
-   * @return This byte string builder.
-   * @throws IndexOutOfBoundsException
-   *           If the <code>newLength</code> argument is negative.
-   */
-  public ByteStringBuilder setLength(final int newLength)
-  {
-    if (newLength < 0)
-    {
-      throw new IndexOutOfBoundsException("Negative newLength: " + newLength);
+    /**
+     * Appends the provided {@link ByteSequence} to this byte string builder.
+     *
+     * @param bytes
+     *            The byte sequence to be appended to this byte string builder.
+     * @return This byte string builder.
+     */
+    public ByteStringBuilder append(final ByteSequence bytes) {
+        return bytes.copyTo(this);
     }
 
-    if (newLength > length)
-    {
-      ensureAdditionalCapacity(newLength - length);
+    /**
+     * Appends the provided {@link ByteSequenceReader} to this byte string
+     * builder.
+     *
+     * @param reader
+     *            The byte sequence reader to be appended to this byte string
+     *            builder.
+     * @param length
+     *            The number of bytes to be appended from {@code reader}.
+     * @return This byte string builder.
+     * @throws IndexOutOfBoundsException
+     *             If {@code length} is less than zero or greater than
+     *             {@code reader.remaining()}.
+     */
+    public ByteStringBuilder append(final ByteSequenceReader reader, final int length) {
+        if (length < 0 || length > reader.remaining()) {
+            throw new IndexOutOfBoundsException();
+        }
 
-      // Pad with zeros.
-      for (int i = length; i < newLength; i++)
-      {
-        buffer[i] = 0;
-      }
-    }
-    length = newLength;
+        if (length != 0) {
+            ensureAdditionalCapacity(length);
+            reader.get(buffer, this.length, length);
+            this.length += length;
+        }
 
-    return this;
-  }
-
-
-
-  /**
-   * Returns a new byte sequence that is a subsequence of this byte sequence.
-   * <p>
-   * The subsequence starts with the byte value at the specified {@code start}
-   * index and ends with the byte value at index {@code end - 1}. The length (in
-   * bytes) of the returned sequence is {@code end - start}, so if {@code start
-   * == end} then an empty sequence is returned.
-   * <p>
-   * <b>NOTE:</b> the returned sub-sequence will be robust against all updates
-   * to the byte string builder except for invocations of the method
-   * {@link #clear()}. If a permanent immutable byte sequence is required then
-   * callers should invoke {@code toByteString()} on the returned byte sequence.
-   *
-   * @param start
-   *          The start index, inclusive.
-   * @param end
-   *          The end index, exclusive.
-   * @return The newly created byte subsequence.
-   */
-  public ByteSequence subSequence(final int start, final int end)
-  {
-    if (start < 0 || start > end || end > length)
-    {
-      throw new IndexOutOfBoundsException();
+        return this;
     }
 
-    return new SubSequence(start, end - start);
-  }
+    /**
+     * Appends the UTF-8 encoded bytes of the provided char array to this byte
+     * string builder.
+     *
+     * @param chars
+     *            The char array whose UTF-8 encoding is to be appended to this
+     *            byte string builder.
+     * @return This byte string builder.
+     */
+    public ByteStringBuilder append(final char[] chars) {
+        if (chars == null) {
+            return this;
+        }
 
+        // Assume that each char is 1 byte
+        final int len = chars.length;
+        ensureAdditionalCapacity(len);
 
+        for (int i = 0; i < len; i++) {
+            final char c = chars[i];
+            final byte b = (byte) (c & 0x0000007F);
 
-  /**
-   * {@inheritDoc}
-   */
-  public byte[] toByteArray()
-  {
-    return copyTo(new byte[length]);
-  }
+            if (c == b) {
+                buffer[this.length + i] = b;
+            } else {
+                // There is a multi-byte char. Defer to JDK.
+                final Charset utf8 = Charset.forName("UTF-8");
+                final ByteBuffer byteBuffer = utf8.encode(CharBuffer.wrap(chars));
+                final int remaining = byteBuffer.remaining();
+                ensureAdditionalCapacity(remaining - len);
+                byteBuffer.get(buffer, this.length, remaining);
+                this.length += remaining;
+                return this;
+            }
+        }
 
+        // The 1 byte char assumption was correct
+        this.length += len;
+        return this;
 
-
-  /**
-   * Returns the {@link ByteString} representation of this byte string builder.
-   * Subsequent changes to this byte string builder will not modify the returned
-   * {@link ByteString}.
-   *
-   * @return The {@link ByteString} representation of this byte sequence.
-   */
-  public ByteString toByteString()
-  {
-    final byte[] b = new byte[length];
-    System.arraycopy(buffer, 0, b, 0, length);
-    return ByteString.wrap(b);
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override
-  public String toString()
-  {
-    return ByteString.toString(buffer, 0, length);
-  }
-
-
-
-  /**
-   * Attempts to reduce storage used for this byte string builder. If the buffer
-   * is larger than necessary to hold its current sequence of bytes, then it may
-   * be resized to become more space efficient.
-   *
-   * @return This byte string builder.
-   */
-  public ByteStringBuilder trimToSize()
-  {
-    if (buffer.length > length)
-    {
-      final byte[] newBuffer = new byte[length];
-      System.arraycopy(buffer, 0, newBuffer, 0, length);
-      buffer = newBuffer;
     }
-    return this;
-  }
+
+    /**
+     * Appends the provided {@code InputStream} to this byte string builder.
+     *
+     * @param stream
+     *            The input stream to be appended to this byte string builder.
+     * @param length
+     *            The maximum number of bytes to be appended from {@code buffer}
+     *            .
+     * @return The number of bytes read from the input stream, or {@code -1} if
+     *         the end of the input stream has been reached.
+     * @throws IndexOutOfBoundsException
+     *             If {@code length} is less than zero.
+     * @throws IOException
+     *             If an I/O error occurs.
+     */
+    public int append(final InputStream stream, final int length) throws IOException {
+        if (length < 0) {
+            throw new IndexOutOfBoundsException();
+        }
+
+        ensureAdditionalCapacity(length);
+        final int bytesRead = stream.read(buffer, this.length, length);
+        if (bytesRead > 0) {
+            this.length += bytesRead;
+        }
+
+        return bytesRead;
+    }
+
+    /**
+     * Appends the big-endian encoded bytes of the provided integer to this byte
+     * string builder.
+     *
+     * @param i
+     *            The integer whose big-endian encoding is to be appended to
+     *            this byte string builder.
+     * @return This byte string builder.
+     */
+    public ByteStringBuilder append(int i) {
+        ensureAdditionalCapacity(4);
+        for (int j = length + 3; j >= length; j--) {
+            buffer[j] = (byte) (i & 0xFF);
+            i >>>= 8;
+        }
+        length += 4;
+        return this;
+    }
+
+    /**
+     * Appends the big-endian encoded bytes of the provided long to this byte
+     * string builder.
+     *
+     * @param l
+     *            The long whose big-endian encoding is to be appended to this
+     *            byte string builder.
+     * @return This byte string builder.
+     */
+    public ByteStringBuilder append(long l) {
+        ensureAdditionalCapacity(8);
+        for (int i = length + 7; i >= length; i--) {
+            buffer[i] = (byte) (l & 0xFF);
+            l >>>= 8;
+        }
+        length += 8;
+        return this;
+    }
+
+    /**
+     * Appends the byte string representation of the provided object to this
+     * byte string builder. The object is converted to a byte string as follows:
+     * <ul>
+     * <li>if the object is an instance of {@code ByteSequence} then this method
+     * is equivalent to calling {@link #append(ByteSequence)}
+     * <li>if the object is a {@code byte[]} then this method is equivalent to
+     * calling {@link #append(byte[])}
+     * <li>if the object is a {@code char[]} then this method is equivalent to
+     * calling {@link #append(char[])}
+     * <li>for all other types of object this method is equivalent to calling
+     * {@link #append(String)} with the {@code toString()} representation of the
+     * provided object.
+     * </ul>
+     * <b>Note:</b> this method treats {@code Long} and {@code Integer} objects
+     * like any other type of {@code Object}. More specifically, the following
+     * invocations are not equivalent:
+     * <ul>
+     * <li>{@code append(0)} is not equivalent to {@code append((Object) 0)}
+     * <li>{@code append(0L)} is not equivalent to {@code append((Object) 0L)}
+     * </ul>
+     *
+     * @param o
+     *            The object to be appended to this byte string builder.
+     * @return This byte string builder.
+     */
+    public ByteStringBuilder append(final Object o) {
+        if (o == null) {
+            return this;
+        } else if (o instanceof ByteSequence) {
+            return append((ByteSequence) o);
+        } else if (o instanceof byte[]) {
+            return append((byte[]) o);
+        } else if (o instanceof char[]) {
+            return append((char[]) o);
+        } else {
+            return append(o.toString());
+        }
+    }
+
+    /**
+     * Appends the big-endian encoded bytes of the provided short to this byte
+     * string builder.
+     *
+     * @param i
+     *            The short whose big-endian encoding is to be appended to this
+     *            byte string builder.
+     * @return This byte string builder.
+     */
+    public ByteStringBuilder append(short i) {
+        ensureAdditionalCapacity(2);
+        for (int j = length + 1; j >= length; j--) {
+            buffer[j] = (byte) (i & 0xFF);
+            i >>>= 8;
+        }
+        length += 2;
+        return this;
+    }
+
+    /**
+     * Appends the UTF-8 encoded bytes of the provided string to this byte
+     * string builder.
+     *
+     * @param s
+     *            The string whose UTF-8 encoding is to be appended to this byte
+     *            string builder.
+     * @return This byte string builder.
+     */
+    public ByteStringBuilder append(final String s) {
+        if (s == null) {
+            return this;
+        }
+
+        // Assume that each char is 1 byte
+        final int len = s.length();
+        ensureAdditionalCapacity(len);
+
+        for (int i = 0; i < len; i++) {
+            final char c = s.charAt(i);
+            final byte b = (byte) (c & 0x0000007F);
+
+            if (c == b) {
+                buffer[this.length + i] = b;
+            } else {
+                // There is a multi-byte char. Defer to JDK
+                try {
+                    return append(s.getBytes("UTF-8"));
+                } catch (final Exception e) {
+                    if (StaticUtils.DEBUG_LOG.isLoggable(Level.WARNING)) {
+                        StaticUtils.DEBUG_LOG.warning("Unable to encode String "
+                                + "to UTF-8 bytes: " + e.toString());
+                    }
+
+                    return append(s.getBytes());
+                }
+            }
+        }
+
+        // The 1 byte char assumption was correct
+        this.length += len;
+        return this;
+    }
+
+    /**
+     * Appends the ASN.1 BER length encoding representation of the provided
+     * integer to this byte string builder.
+     *
+     * @param length
+     *            The value to encode using the BER length encoding rules.
+     * @return This byte string builder.
+     */
+    public ByteStringBuilder appendBERLength(final int length) {
+        if ((length & 0x0000007F) == length) {
+            ensureAdditionalCapacity(1);
+
+            buffer[this.length++] = (byte) (length & 0xFF);
+        } else if ((length & 0x000000FF) == length) {
+            ensureAdditionalCapacity(2);
+
+            buffer[this.length++] = (byte) 0x81;
+            buffer[this.length++] = (byte) (length & 0xFF);
+        } else if ((length & 0x0000FFFF) == length) {
+            ensureAdditionalCapacity(3);
+
+            buffer[this.length++] = (byte) 0x82;
+            buffer[this.length++] = (byte) (length >> 8 & 0xFF);
+            buffer[this.length++] = (byte) (length & 0xFF);
+        } else if ((length & 0x00FFFFFF) == length) {
+            ensureAdditionalCapacity(4);
+
+            buffer[this.length++] = (byte) 0x83;
+            buffer[this.length++] = (byte) (length >> 16 & 0xFF);
+            buffer[this.length++] = (byte) (length >> 8 & 0xFF);
+            buffer[this.length++] = (byte) (length & 0xFF);
+        } else {
+            ensureAdditionalCapacity(5);
+
+            buffer[this.length++] = (byte) 0x84;
+            buffer[this.length++] = (byte) (length >> 24 & 0xFF);
+            buffer[this.length++] = (byte) (length >> 16 & 0xFF);
+            buffer[this.length++] = (byte) (length >> 8 & 0xFF);
+            buffer[this.length++] = (byte) (length & 0xFF);
+        }
+        return this;
+    }
+
+    /**
+     * Returns a {@link ByteSequenceReader} which can be used to incrementally
+     * read and decode data from this byte string builder.
+     * <p>
+     * <b>NOTE:</b> all concurrent updates to this byte string builder are
+     * supported with the exception of {@link #clear()}. Any invocations of
+     * {@link #clear()} must be accompanied by a subsequent call to
+     * {@code ByteSequenceReader.rewind()}.
+     *
+     * @return The {@link ByteSequenceReader} which can be used to incrementally
+     *         read and decode data from this byte string builder.
+     * @see #clear()
+     */
+    public ByteSequenceReader asReader() {
+        return new ByteSequenceReader(this);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public byte byteAt(final int index) {
+        if (index >= length || index < 0) {
+            throw new IndexOutOfBoundsException();
+        }
+        return buffer[index];
+    }
+
+    /**
+     * Sets the length of this byte string builder to zero.
+     * <p>
+     * <b>NOTE:</b> if this method is called, then
+     * {@code ByteSequenceReader.rewind()} must also be called on any associated
+     * byte sequence readers in order for them to remain valid.
+     *
+     * @return This byte string builder.
+     * @see #asReader()
+     */
+    public ByteStringBuilder clear() {
+        length = 0;
+        return this;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public int compareTo(final byte[] bytes, final int offset, final int length) {
+        ByteString.checkArrayBounds(bytes, offset, length);
+        return ByteString.compareTo(this.buffer, 0, this.length, bytes, offset, length);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public int compareTo(final ByteSequence o) {
+        if (this == o) {
+            return 0;
+        }
+        return -o.compareTo(buffer, 0, length);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public byte[] copyTo(final byte[] bytes) {
+        copyTo(bytes, 0);
+        return bytes;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public byte[] copyTo(final byte[] bytes, final int offset) {
+        if (offset < 0) {
+            throw new IndexOutOfBoundsException();
+        }
+        System.arraycopy(buffer, 0, bytes, offset, Math.min(length, bytes.length - offset));
+        return bytes;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public ByteStringBuilder copyTo(final ByteStringBuilder builder) {
+        builder.append(buffer, 0, length);
+        return builder;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public OutputStream copyTo(final OutputStream stream) throws IOException {
+        stream.write(buffer, 0, length);
+        return stream;
+    }
+
+    /**
+     * Ensures that the specified number of additional bytes will fit in this
+     * byte string builder and resizes it if necessary.
+     *
+     * @param size
+     *            The number of additional bytes.
+     * @return This byte string builder.
+     */
+    public ByteStringBuilder ensureAdditionalCapacity(final int size) {
+        final int newCount = this.length + size;
+        if (newCount > buffer.length) {
+            final byte[] newbuffer = new byte[Math.max(buffer.length << 1, newCount)];
+            System.arraycopy(buffer, 0, newbuffer, 0, buffer.length);
+            buffer = newbuffer;
+        }
+        return this;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean equals(final byte[] bytes, final int offset, final int length) {
+        ByteString.checkArrayBounds(bytes, offset, length);
+        return ByteString.equals(this.buffer, 0, this.length, bytes, offset, length);
+    }
+
+    /**
+     * Indicates whether the provided object is equal to this byte string
+     * builder. In order for it to be considered equal, the provided object must
+     * be a byte sequence containing the same bytes in the same order.
+     *
+     * @param o
+     *            The object for which to make the determination.
+     * @return {@code true} if the provided object is a byte sequence whose
+     *         content is equal to that of this byte string builder, or
+     *         {@code false} if not.
+     */
+    @Override
+    public boolean equals(final Object o) {
+        if (this == o) {
+            return true;
+        } else if (o instanceof ByteSequence) {
+            final ByteSequence other = (ByteSequence) o;
+            return other.equals(buffer, 0, length);
+        } else {
+            return false;
+        }
+    }
+
+    /**
+     * Returns the byte array that backs this byte string builder. Modifications
+     * to this byte string builder's content may cause the returned array's
+     * content to be modified, and vice versa.
+     * <p>
+     * Note that the length of the returned array is only guaranteed to be the
+     * same as the length of this byte string builder immediately after a call
+     * to {@link #trimToSize()}.
+     * <p>
+     * In addition, subsequent modifications to this byte string builder may
+     * cause the backing byte array to be reallocated thus decoupling the
+     * returned byte array from this byte string builder.
+     *
+     * @return The byte array that backs this byte string builder.
+     */
+    public byte[] getBackingArray() {
+        return buffer;
+    }
+
+    /**
+     * Returns a hash code for this byte string builder. It will be the sum of
+     * all of the bytes contained in the byte string builder.
+     * <p>
+     * <b>NOTE:</b> subsequent changes to this byte string builder will
+     * invalidate the returned hash code.
+     *
+     * @return A hash code for this byte string builder.
+     */
+    @Override
+    public int hashCode() {
+        return ByteString.hashCode(buffer, 0, length);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public int length() {
+        return length;
+    }
+
+    /**
+     * Sets the length of this byte string builder.
+     * <p>
+     * If the <code>newLength</code> argument is less than the current length,
+     * the length is changed to the specified length.
+     * <p>
+     * If the <code>newLength</code> argument is greater than or equal to the
+     * current length, then the capacity is increased and sufficient null bytes
+     * are appended so that length becomes the <code>newLength</code> argument.
+     * <p>
+     * The <code>newLength</code> argument must be greater than or equal to
+     * <code>0</code>.
+     *
+     * @param newLength
+     *            The new length.
+     * @return This byte string builder.
+     * @throws IndexOutOfBoundsException
+     *             If the <code>newLength</code> argument is negative.
+     */
+    public ByteStringBuilder setLength(final int newLength) {
+        if (newLength < 0) {
+            throw new IndexOutOfBoundsException("Negative newLength: " + newLength);
+        }
+
+        if (newLength > length) {
+            ensureAdditionalCapacity(newLength - length);
+
+            // Pad with zeros.
+            for (int i = length; i < newLength; i++) {
+                buffer[i] = 0;
+            }
+        }
+        length = newLength;
+
+        return this;
+    }
+
+    /**
+     * Returns a new byte sequence that is a subsequence of this byte sequence.
+     * <p>
+     * The subsequence starts with the byte value at the specified {@code start}
+     * index and ends with the byte value at index {@code end - 1}. The length
+     * (in bytes) of the returned sequence is {@code end - start}, so if
+     * {@code start
+     * == end} then an empty sequence is returned.
+     * <p>
+     * <b>NOTE:</b> the returned sub-sequence will be robust against all updates
+     * to the byte string builder except for invocations of the method
+     * {@link #clear()}. If a permanent immutable byte sequence is required then
+     * callers should invoke {@code toByteString()} on the returned byte
+     * sequence.
+     *
+     * @param start
+     *            The start index, inclusive.
+     * @param end
+     *            The end index, exclusive.
+     * @return The newly created byte subsequence.
+     */
+    public ByteSequence subSequence(final int start, final int end) {
+        if (start < 0 || start > end || end > length) {
+            throw new IndexOutOfBoundsException();
+        }
+
+        return new SubSequence(start, end - start);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public byte[] toByteArray() {
+        return copyTo(new byte[length]);
+    }
+
+    /**
+     * Returns the {@link ByteString} representation of this byte string
+     * builder. Subsequent changes to this byte string builder will not modify
+     * the returned {@link ByteString}.
+     *
+     * @return The {@link ByteString} representation of this byte sequence.
+     */
+    public ByteString toByteString() {
+        final byte[] b = new byte[length];
+        System.arraycopy(buffer, 0, b, 0, length);
+        return ByteString.wrap(b);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public String toString() {
+        return ByteString.toString(buffer, 0, length);
+    }
+
+    /**
+     * Attempts to reduce storage used for this byte string builder. If the
+     * buffer is larger than necessary to hold its current sequence of bytes,
+     * then it may be resized to become more space efficient.
+     *
+     * @return This byte string builder.
+     */
+    public ByteStringBuilder trimToSize() {
+        if (buffer.length > length) {
+            final byte[] newBuffer = new byte[length];
+            System.arraycopy(buffer, 0, newBuffer, 0, length);
+            buffer = newBuffer;
+        }
+        return this;
+    }
 }

--
Gitblit v1.10.0