// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc.  All rights reserved.
// 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.

package com.google.protobuf;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.io.ByteArrayInputStream;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.Stack;

/**
 * Class to represent {@code ByteStrings} formed by concatenation of other
 * ByteStrings, without copying the data in the pieces. The concatenation is
 * represented as a tree whose leaf nodes are each a {@link LiteralByteString}.
 *
 * <p>Most of the operation here is inspired by the now-famous paper <a
 * href="http://www.cs.ubc.ca/local/reading/proceedings/spe91-95/spe/vol25/issue12/spe986.pdf">
 * BAP95 </a> Ropes: an Alternative to Strings hans-j. boehm, russ atkinson and
 * michael plass
 *
 * <p>The algorithms described in the paper have been implemented for character
 * strings in {@link com.google.common.string.Rope} and in the c++ class {@code
 * cord.cc}.
 *
 * <p>Fundamentally the Rope algorithm represents the collection of pieces as a
 * binary tree. BAP95 uses a Fibonacci bound relating depth to a minimum
 * sequence length, sequences that are too short relative to their depth cause a
 * tree rebalance.  More precisely, a tree of depth d is "balanced" in the
 * terminology of BAP95 if its length is at least F(d+2), where F(n) is the
 * n-the Fibonacci number. Thus for depths 0, 1, 2, 3, 4, 5,... we have minimum
 * lengths 1, 2, 3, 5, 8, 13,...
 *
 * @author carlanton@google.com (Carl Haverl)
 */
class RopeByteString extends ByteString {

  /**
   * BAP95. Let Fn be the nth Fibonacci number. A {@link RopeByteString} of
   * depth n is "balanced", i.e flat enough, if its length is at least Fn+2,
   * e.g. a "balanced" {@link RopeByteString} of depth 1 must have length at
   * least 2, of depth 4 must have length >= 8, etc.
   *
   * <p>There's nothing special about using the Fibonacci numbers for this, but
   * they are a reasonable sequence for encapsulating the idea that we are OK
   * with longer strings being encoded in deeper binary trees.
   *
   * <p>For 32-bit integers, this array has length 46.
   */
  private static final int[] minLengthByDepth;

  static {
    // Dynamically generate the list of Fibonacci numbers the first time this
    // class is accessed.
    List<Integer> numbers = new ArrayList<Integer>();

    // we skip the first Fibonacci number (1).  So instead of: 1 1 2 3 5 8 ...
    // we have: 1 2 3 5 8 ...
    int f1 = 1;
    int f2 = 1;

    // get all the values until we roll over.
    while (f2 > 0) {
      numbers.add(f2);
      int temp = f1 + f2;
      f1 = f2;
      f2 = temp;
    }

    // we include this here so that we can index this array to [x + 1] in the
    // loops below.
    numbers.add(Integer.MAX_VALUE);
    minLengthByDepth = new int[numbers.size()];
    for (int i = 0; i < minLengthByDepth.length; i++) {
      // unbox all the values
      minLengthByDepth[i] = numbers.get(i);
    }
  }

  private final int totalLength;
  private final ByteString left;
  private final ByteString right;
  private final int leftLength;
  private final int treeDepth;

  /**
   * Create a new RopeByteString, which can be thought of as a new tree node, by
   * recording references to the two given strings.
   *
   * @param left  string on the left of this node, should have {@code size() >
   *              0}
   * @param right string on the right of this node, should have {@code size() >
   *              0}
   */
  private RopeByteString(ByteString left, ByteString right) {
    this.left = left;
    this.right = right;
    leftLength = left.size();
    totalLength = leftLength + right.size();
    treeDepth = Math.max(left.getTreeDepth(), right.getTreeDepth()) + 1;
  }

  /**
   * Concatenate the given strings while performing various optimizations to
   * slow the growth rate of tree depth and tree node count. The result is
   * either a {@link LiteralByteString} or a {@link RopeByteString}
   * depending on which optimizations, if any, were applied.
   *
   * <p>Small pieces of length less than {@link
   * ByteString#CONCATENATE_BY_COPY_SIZE} may be copied by value here, as in
   * BAP95.  Large pieces are referenced without copy.
   *
   * @param left  string on the left
   * @param right string on the right
   * @return concatenation representing the same sequence as the given strings
   */
  static ByteString concatenate(ByteString left, ByteString right) {
    ByteString result;
    RopeByteString leftRope =
        (left instanceof RopeByteString) ? (RopeByteString) left : null;
    if (right.size() == 0) {
      result = left;
    } else if (left.size() == 0) {
      result = right;
    } else {
      int newLength = left.size() + right.size();
      if (newLength < ByteString.CONCATENATE_BY_COPY_SIZE) {
        // Optimization from BAP95: For short (leaves in paper, but just short
        // here) total length, do a copy of data to a new leaf.
        result = concatenateBytes(left, right);
      } else if (leftRope != null
          && leftRope.right.size() + right.size() < CONCATENATE_BY_COPY_SIZE) {
        // Optimization from BAP95: As an optimization of the case where the
        // ByteString is constructed by repeated concatenate, recognize the case
        // where a short string is concatenated to a left-hand node whose
        // right-hand branch is short.  In the paper this applies to leaves, but
        // we just look at the length here. This has the advantage of shedding
        // references to unneeded data when substrings have been taken.
        //
        // When we recognize this case, we do a copy of the data and create a
        // new parent node so that the depth of the result is the same as the
        // given left tree.
        ByteString newRight = concatenateBytes(leftRope.right, right);
        result = new RopeByteString(leftRope.left, newRight);
      } else if (leftRope != null
          && leftRope.left.getTreeDepth() > leftRope.right.getTreeDepth()
          && leftRope.getTreeDepth() > right.getTreeDepth()) {
        // Typically for concatenate-built strings the left-side is deeper than
        // the right.  This is our final attempt to concatenate without
        // increasing the tree depth.  We'll redo the the node on the RHS.  This
        // is yet another optimization for building the string by repeatedly
        // concatenating on the right.
        ByteString newRight = new RopeByteString(leftRope.right, right);
        result = new RopeByteString(leftRope.left, newRight);
      } else {
        // Fine, we'll add a node and increase the tree depth--unless we
        // rebalance ;^)
        int newDepth = Math.max(left.getTreeDepth(), right.getTreeDepth()) + 1;
        if (newLength >= minLengthByDepth[newDepth]) {
          // The tree is shallow enough, so don't rebalance
          result = new RopeByteString(left, right);
        } else {
          result = new Balancer().balance(left, right);
        }
      }
    }
    return result;
  }

  /**
   * Concatenates two strings by copying data values. This is called in a few
   * cases in order to reduce the growth of the number of tree nodes.
   *
   * @param left  string on the left
   * @param right string on the right
   * @return string formed by copying data bytes
   */
  private static LiteralByteString concatenateBytes(ByteString left,
      ByteString right) {
    int leftSize = left.size();
    int rightSize = right.size();
    byte[] bytes = new byte[leftSize + rightSize];
    left.copyTo(bytes, 0, 0, leftSize);
    right.copyTo(bytes, 0, leftSize, rightSize);
    return new LiteralByteString(bytes);  // Constructor wraps bytes
  }

  /**
   * Create a new RopeByteString for testing only while bypassing all the
   * defenses of {@link #concatenate(ByteString, ByteString)}. This allows
   * testing trees of specific structure. We are also able to insert empty
   * leaves, though these are dis-allowed, so that we can make sure the
   * implementation can withstand their presence.
   *
   * @param left  string on the left of this node
   * @param right string on the right of this node
   * @return an unsafe instance for testing only
   */
  static RopeByteString newInstanceForTest(ByteString left, ByteString right) {
    return new RopeByteString(left, right);
  }

  /**
   * Gets the byte at the given index.
   * Throws {@link ArrayIndexOutOfBoundsException} for backwards-compatibility
   * reasons although it would more properly be {@link
   * IndexOutOfBoundsException}.
   *
   * @param index index of byte
   * @return the value
   * @throws ArrayIndexOutOfBoundsException {@code index} is < 0 or >= size
   */
  @Override
  public byte byteAt(int index) {
    if (index < 0) {
      throw new ArrayIndexOutOfBoundsException("Index < 0: " + index);
    }
    if (index > totalLength) {
      throw new ArrayIndexOutOfBoundsException(
          "Index > length: " + index + ", " + totalLength);
    }

    byte result;
    // Find the relevant piece by recursive descent
    if (index < leftLength) {
      result = left.byteAt(index);
    } else {
      result = right.byteAt(index - leftLength);
    }
    return result;
  }

  @Override
  public int size() {
    return totalLength;
  }

  // =================================================================
  // Pieces

  @Override
  protected int getTreeDepth() {
    return treeDepth;
  }

  /**
   * Determines if the tree is balanced according to BAP95, which means the tree
   * is flat-enough with respect to the bounds. Note that this definition of
   * balanced is one where sub-trees of balanced trees are not necessarily
   * balanced.
   *
   * @return true if the tree is balanced
   */
  @Override
  protected boolean isBalanced() {
    return totalLength >= minLengthByDepth[treeDepth];
  }

  /**
   * Takes a substring of this one. This involves recursive descent along the
   * left and right edges of the substring, and referencing any wholly contained
   * segments in between. Any leaf nodes entirely uninvolved in the substring
   * will not be referenced by the substring.
   *
   * <p>Substrings of {@code length < 2} should result in at most a single
   * recursive call chain, terminating at a leaf node. Thus the result will be a
   * {@link LiteralByteString}. {@link #RopeByteString(ByteString,
   * ByteString)}.
   *
   * @param beginIndex start at this index
   * @param endIndex   the last character is the one before this index
   * @return substring leaf node or tree
   */
  @Override
  public ByteString substring(int beginIndex, int endIndex) {
    if (beginIndex < 0) {
      throw new IndexOutOfBoundsException(
          "Beginning index: " + beginIndex + " < 0");
    }
    if (endIndex > totalLength) {
      throw new IndexOutOfBoundsException(
          "End index: " + endIndex + " > " + totalLength);
    }
    int substringLength = endIndex - beginIndex;
    if (substringLength < 0) {
      throw new IndexOutOfBoundsException(
          "Beginning index larger than ending index: " + beginIndex + ", "
              + endIndex);
    }

    ByteString result;
    if (substringLength == 0) {
      // Empty substring
      result = ByteString.EMPTY;
    } else if (substringLength == totalLength) {
      // The whole string
      result = this;
    } else {
      // Proper substring
      if (endIndex <= leftLength) {
        // Substring on the left
        result = left.substring(beginIndex, endIndex);
      } else if (beginIndex >= leftLength) {
        // Substring on the right
        result = right
            .substring(beginIndex - leftLength, endIndex - leftLength);
      } else {
        // Split substring
        ByteString leftSub = left.substring(beginIndex);
        ByteString rightSub = right.substring(0, endIndex - leftLength);
        // Intentionally not rebalancing, since in many cases these two
        // substrings will already be less deep than the top-level
        // RopeByteString we're taking a substring of.
        result = new RopeByteString(leftSub, rightSub);
      }
    }
    return result;
  }

  // =================================================================
  // ByteString -> byte[]

  @Override
  protected void copyToInternal(byte[] target, int sourceOffset,
      int targetOffset, int numberToCopy) {
   if (sourceOffset + numberToCopy <= leftLength) {
      left.copyToInternal(target, sourceOffset, targetOffset, numberToCopy);
    } else if (sourceOffset >= leftLength) {
      right.copyToInternal(target, sourceOffset - leftLength, targetOffset,
          numberToCopy);
    } else {
      int leftLength = this.leftLength - sourceOffset;
      left.copyToInternal(target, sourceOffset, targetOffset, leftLength);
      right.copyToInternal(target, 0, targetOffset + leftLength,
          numberToCopy - leftLength);
    }
  }

  @Override
  public void copyTo(ByteBuffer target) {
    left.copyTo(target);
    right.copyTo(target);
  }

  @Override
  public ByteBuffer asReadOnlyByteBuffer() {
    ByteBuffer byteBuffer = ByteBuffer.wrap(toByteArray());
    return byteBuffer.asReadOnlyBuffer();
  }

  @Override
  public List<ByteBuffer> asReadOnlyByteBufferList() {
    // Walk through the list of LiteralByteString's that make up this
    // rope, and add each one as a read-only ByteBuffer.
    List<ByteBuffer> result = new ArrayList<ByteBuffer>();
    PieceIterator pieces = new PieceIterator(this);
    while (pieces.hasNext()) {
      LiteralByteString byteString = pieces.next();
      result.add(byteString.asReadOnlyByteBuffer());
    }
    return result;
  }

  @Override
  public void writeTo(OutputStream outputStream) throws IOException {
    left.writeTo(outputStream);
    right.writeTo(outputStream);
  }

  @Override
  public String toString(String charsetName)
      throws UnsupportedEncodingException {
    return new String(toByteArray(), charsetName);
  }

  // =================================================================
  // UTF-8 decoding

  @Override
  public boolean isValidUtf8() {
    int leftPartial = left.partialIsValidUtf8(Utf8.COMPLETE, 0, leftLength);
    int state = right.partialIsValidUtf8(leftPartial, 0, right.size());
    return state == Utf8.COMPLETE;
  }

  @Override
  protected int partialIsValidUtf8(int state, int offset, int length) {
    int toIndex = offset + length;
    if (toIndex <= leftLength) {
      return left.partialIsValidUtf8(state, offset, length);
    } else if (offset >= leftLength) {
      return right.partialIsValidUtf8(state, offset - leftLength, length);
    } else {
      int leftLength = this.leftLength - offset;
      int leftPartial = left.partialIsValidUtf8(state, offset, leftLength);
      return right.partialIsValidUtf8(leftPartial, 0, length - leftLength);
    }
  }

  // =================================================================
  // equals() and hashCode()

  @Override
  public boolean equals(Object other) {
    if (other == this) {
      return true;
    }
    if (!(other instanceof ByteString)) {
      return false;
    }

    ByteString otherByteString = (ByteString) other;
    if (totalLength != otherByteString.size()) {
      return false;
    }
    if (totalLength == 0) {
      return true;
    }

    // You don't really want to be calling equals on long strings, but since
    // we cache the hashCode, we effectively cache inequality. We use the cached
    // hashCode if it's already computed.  It's arguable we should compute the
    // hashCode here, and if we're going to be testing a bunch of byteStrings,
    // it might even make sense.
    if (hash != 0) {
      int cachedOtherHash = otherByteString.peekCachedHashCode();
      if (cachedOtherHash != 0 && hash != cachedOtherHash) {
        return false;
      }
    }

    return equalsFragments(otherByteString);
  }

  /**
   * Determines if this string is equal to another of the same length by
   * iterating over the leaf nodes. On each step of the iteration, the
   * overlapping segments of the leaves are compared.
   *
   * @param other string of the same length as this one
   * @return true if the values of this string equals the value of the given
   *         one
   */
  private boolean equalsFragments(ByteString other) {
    int thisOffset = 0;
    Iterator<LiteralByteString> thisIter = new PieceIterator(this);
    LiteralByteString thisString = thisIter.next();

    int thatOffset = 0;
    Iterator<LiteralByteString> thatIter = new PieceIterator(other);
    LiteralByteString thatString = thatIter.next();

    int pos = 0;
    while (true) {
      int thisRemaining = thisString.size() - thisOffset;
      int thatRemaining = thatString.size() - thatOffset;
      int bytesToCompare = Math.min(thisRemaining, thatRemaining);

      // At least one of the offsets will be zero
      boolean stillEqual = (thisOffset == 0)
          ? thisString.equalsRange(thatString, thatOffset, bytesToCompare)
          : thatString.equalsRange(thisString, thisOffset, bytesToCompare);
      if (!stillEqual) {
        return false;
      }

      pos += bytesToCompare;
      if (pos >= totalLength) {
        if (pos == totalLength) {
          return true;
        }
        throw new IllegalStateException();
      }
      // We always get to the end of at least one of the pieces
      if (bytesToCompare == thisRemaining) { // If reached end of this
        thisOffset = 0;
        thisString = thisIter.next();
      } else {
        thisOffset += bytesToCompare;
      }
      if (bytesToCompare == thatRemaining) { // If reached end of that
        thatOffset = 0;
        thatString = thatIter.next();
      } else {
        thatOffset += bytesToCompare;
      }
    }
  }

  /**
   * Cached hash value.  Intentionally accessed via a data race, which is safe
   * because of the Java Memory Model's "no out-of-thin-air values" guarantees
   * for ints.
   */
  private int hash = 0;

  @Override
  public int hashCode() {
    int h = hash;

    if (h == 0) {
      h = totalLength;
      h = partialHash(h, 0, totalLength);
      if (h == 0) {
        h = 1;
      }
      hash = h;
    }
    return h;
  }

  @Override
  protected int peekCachedHashCode() {
    return hash;
  }

  @Override
  protected int partialHash(int h, int offset, int length) {
    int toIndex = offset + length;
    if (toIndex <= leftLength) {
      return left.partialHash(h, offset, length);
    } else if (offset >= leftLength) {
      return right.partialHash(h, offset - leftLength, length);
    } else {
      int leftLength = this.leftLength - offset;
      int leftPartial = left.partialHash(h, offset, leftLength);
      return right.partialHash(leftPartial, 0, length - leftLength);
    }
  }

  // =================================================================
  // Input stream

  @Override
  public CodedInputStream newCodedInput() {
    return CodedInputStream.newInstance(new RopeInputStream());
  }

  @Override
  public InputStream newInput() {
    return new RopeInputStream();
  }

  /**
   * This class implements the balancing algorithm of BAP95. In the paper the
   * authors use an array to keep track of pieces, while here we use a stack.
   * The tree is balanced by traversing subtrees in left to right order, and the
   * stack always contains the part of the string we've traversed so far.
   *
   * <p>One surprising aspect of the algorithm is the result of balancing is not
   * necessarily balanced, though it is nearly balanced.  For details, see
   * BAP95.
   */
  private static class Balancer {
    // Stack containing the part of the string, starting from the left, that
    // we've already traversed.  The final string should be the equivalent of
    // concatenating the strings on the stack from bottom to top.
    private final Stack<ByteString> prefixesStack = new Stack<ByteString>();

    private ByteString balance(ByteString left, ByteString right) {
      doBalance(left);
      doBalance(right);

      // Sweep stack to gather the result
      ByteString partialString = prefixesStack.pop();
      while (!prefixesStack.isEmpty()) {
        ByteString newLeft = prefixesStack.pop();
        partialString = new RopeByteString(newLeft, partialString);
      }
      // We should end up with a RopeByteString since at a minimum we will
      // create one from concatenating left and right
      return partialString;
    }

    private void doBalance(ByteString root) {
      // BAP95: Insert balanced subtrees whole. This means the result might not
      // be balanced, leading to repeated rebalancings on concatenate. However,
      // these rebalancings are shallow due to ignoring balanced subtrees, and
      // relatively few calls to insert() result.
      if (root.isBalanced()) {
        insert(root);
      } else if (root instanceof RopeByteString) {
        RopeByteString rbs = (RopeByteString) root;
        doBalance(rbs.left);
        doBalance(rbs.right);
      } else {
        throw new IllegalArgumentException(
            "Has a new type of ByteString been created? Found " +
                root.getClass());
      }
    }

    /**
     * Push a string on the balance stack (BAP95).  BAP95 uses an array and
     * calls the elements in the array 'bins'.  We instead use a stack, so the
     * 'bins' of lengths are represented by differences between the elements of
     * minLengthByDepth.
     *
     * <p>If the length bin for our string, and all shorter length bins, are
     * empty, we just push it on the stack.  Otherwise, we need to start
     * concatenating, putting the given string in the "middle" and continuing
     * until we land in an empty length bin that matches the length of our
     * concatenation.
     *
     * @param byteString string to place on the balance stack
     */
    private void insert(ByteString byteString) {
      int depthBin = getDepthBinForLength(byteString.size());
      int binEnd = minLengthByDepth[depthBin + 1];

      // BAP95: Concatenate all trees occupying bins representing the length of
      // our new piece or of shorter pieces, to the extent that is possible.
      // The goal is to clear the bin which our piece belongs in, but that may
      // not be entirely possible if there aren't enough longer bins occupied.
      if (prefixesStack.isEmpty() || prefixesStack.peek().size() >= binEnd) {
        prefixesStack.push(byteString);
      } else {
        int binStart = minLengthByDepth[depthBin];

        // Concatenate the subtrees of shorter length
        ByteString newTree = prefixesStack.pop();
        while (!prefixesStack.isEmpty()
            && prefixesStack.peek().size() < binStart) {
          ByteString left = prefixesStack.pop();
          newTree = new RopeByteString(left, newTree);
        }

        // Concatenate the given string
        newTree = new RopeByteString(newTree, byteString);

        // Continue concatenating until we land in an empty bin
        while (!prefixesStack.isEmpty()) {
          depthBin = getDepthBinForLength(newTree.size());
          binEnd = minLengthByDepth[depthBin + 1];
          if (prefixesStack.peek().size() < binEnd) {
            ByteString left = prefixesStack.pop();
            newTree = new RopeByteString(left, newTree);
          } else {
            break;
          }
        }
        prefixesStack.push(newTree);
      }
    }

    private int getDepthBinForLength(int length) {
      int depth = Arrays.binarySearch(minLengthByDepth, length);
      if (depth < 0) {
        // It wasn't an exact match, so convert to the index of the containing
        // fragment, which is one less even than the insertion point.
        int insertionPoint = -(depth + 1);
        depth = insertionPoint - 1;
      }

      return depth;
    }
  }

  /**
   * This class is a continuable tree traversal, which keeps the state
   * information which would exist on the stack in a recursive traversal instead
   * on a stack of "Bread Crumbs". The maximum depth of the stack in this
   * iterator is the same as the depth of the tree being traversed.
   *
   * <p>This iterator is used to implement
   * {@link RopeByteString#equalsFragments(ByteString)}.
   */
  private static class PieceIterator implements Iterator<LiteralByteString> {

    private final Stack<RopeByteString> breadCrumbs =
        new Stack<RopeByteString>();
    private LiteralByteString next;

    private PieceIterator(ByteString root) {
      next = getLeafByLeft(root);
    }

    private LiteralByteString getLeafByLeft(ByteString root) {
      ByteString pos = root;
      while (pos instanceof RopeByteString) {
        RopeByteString rbs = (RopeByteString) pos;
        breadCrumbs.push(rbs);
        pos = rbs.left;
      }
      return (LiteralByteString) pos;
    }

    private LiteralByteString getNextNonEmptyLeaf() {
      while (true) {
        // Almost always, we go through this loop exactly once.  However, if
        // we discover an empty string in the rope, we toss it and try again.
        if (breadCrumbs.isEmpty()) {
          return null;
        } else {
          LiteralByteString result = getLeafByLeft(breadCrumbs.pop().right);
          if (!result.isEmpty()) {
            return result;
          }
        }
      }
    }

    public boolean hasNext() {
      return next != null;
    }

    /**
     * Returns the next item and advances one {@code LiteralByteString}.
     *
     * @return next non-empty LiteralByteString or {@code null}
     */
    public LiteralByteString next() {
      if (next == null) {
        throw new NoSuchElementException();
      }
      LiteralByteString result = next;
      next = getNextNonEmptyLeaf();
      return result;
    }

    public void remove() {
      throw new UnsupportedOperationException();
    }
  }

  // =================================================================
  // ByteIterator

  @Override
  public ByteIterator iterator() {
    return new RopeByteIterator();
  }

  private class RopeByteIterator implements ByteString.ByteIterator {

    private final PieceIterator pieces;
    private ByteIterator bytes;
    int bytesRemaining;

    private RopeByteIterator() {
      pieces = new PieceIterator(RopeByteString.this);
      bytes = pieces.next().iterator();
      bytesRemaining = size();
    }

    public boolean hasNext() {
      return (bytesRemaining > 0);
    }

    public Byte next() {
      return nextByte(); // Does not instantiate a Byte
    }

    public byte nextByte() {
      if (!bytes.hasNext()) {
        bytes = pieces.next().iterator();
      }
      --bytesRemaining;
      return bytes.nextByte();
    }

    public void remove() {
      throw new UnsupportedOperationException();
    }
  }

  /**
   * This class is the {@link RopeByteString} equivalent for
   * {@link ByteArrayInputStream}.
   */
  private class RopeInputStream extends InputStream {
    // Iterates through the pieces of the rope
    private PieceIterator pieceIterator;
    // The current piece
    private LiteralByteString currentPiece;
    // The size of the current piece
    private int currentPieceSize;
    // The index of the next byte to read in the current piece
    private int currentPieceIndex;
    // The offset of the start of the current piece in the rope byte string
    private int currentPieceOffsetInRope;
    // Offset in the buffer at which user called mark();
    private int mark;

    public RopeInputStream() {
      initialize();
    }

    @Override
    public int read(byte b[], int offset, int length)  {
      if (b == null) {
        throw new NullPointerException();
      } else if (offset < 0 || length < 0 || length > b.length - offset) {
        throw new IndexOutOfBoundsException();
      }
      return readSkipInternal(b, offset, length);
    }

    @Override
    public long skip(long length) {
      if (length < 0) {
        throw new IndexOutOfBoundsException();
      } else if (length > Integer.MAX_VALUE) {
        length = Integer.MAX_VALUE;
      }
      return readSkipInternal(null, 0, (int) length);
    }

    /**
     * Internal implementation of read and skip.  If b != null, then read the
     * next {@code length} bytes into the buffer {@code b} at
     * offset {@code offset}.  If b == null, then skip the next {@code length)
     * bytes.
     * <p>
     * This method assumes that all error checking has already happened.
     * <p>
     * Returns the actual number of bytes read or skipped.
     */
    private int readSkipInternal(byte b[], int offset, int length)  {
      int bytesRemaining = length;
      while (bytesRemaining > 0) {
        advanceIfCurrentPieceFullyRead();
        if (currentPiece == null) {
          if (bytesRemaining == length) {
             // We didn't manage to read anything
             return -1;
           }
          break;
        } else {
          // Copy the bytes from this piece.
          int currentPieceRemaining = currentPieceSize - currentPieceIndex;
          int count = Math.min(currentPieceRemaining, bytesRemaining);
          if (b != null) {
            currentPiece.copyTo(b, currentPieceIndex, offset, count);
            offset += count;
          }
          currentPieceIndex += count;
          bytesRemaining -= count;
        }
      }
       // Return the number of bytes read.
      return length - bytesRemaining;
    }

    @Override
    public int read() throws IOException {
      advanceIfCurrentPieceFullyRead();
      if (currentPiece == null) {
        return -1;
      } else {
        return currentPiece.byteAt(currentPieceIndex++) & 0xFF;
      }
    }

    @Override
    public int available() throws IOException {
      int bytesRead = currentPieceOffsetInRope + currentPieceIndex;
      return RopeByteString.this.size() - bytesRead;
    }

    @Override
    public boolean markSupported() {
      return true;
    }

    @Override
    public void mark(int readAheadLimit) {
      // Set the mark to our position in the byte string
      mark = currentPieceOffsetInRope + currentPieceIndex;
    }

    @Override
    public synchronized void reset() {
      // Just reinitialize and skip the specified number of bytes.
      initialize();
      readSkipInternal(null, 0, mark);
    }

    /** Common initialization code used by both the constructor and reset() */
    private void initialize() {
      pieceIterator = new PieceIterator(RopeByteString.this);
      currentPiece = pieceIterator.next();
      currentPieceSize = currentPiece.size();
      currentPieceIndex = 0;
      currentPieceOffsetInRope = 0;
    }

    /**
     * Skips to the next piece if we have read all the data in the current
     * piece.  Sets currentPiece to null if we have reached the end of the
     * input.
     */
    private void advanceIfCurrentPieceFullyRead() {
      if (currentPiece != null && currentPieceIndex == currentPieceSize) {
        // Generally, we can only go through this loop at most once, since
        // empty strings can't end up in a rope.  But better to test.
        currentPieceOffsetInRope += currentPieceSize;
        currentPieceIndex = 0;
        if (pieceIterator.hasNext()) {
          currentPiece = pieceIterator.next();
          currentPieceSize = currentPiece.size();
        } else {
          currentPiece = null;
          currentPieceSize = 0;
        }
      }
    }
  }
}
