static <K, V> Node<K, V>[] doubleCapacity(Node<K, V>[] oldTable) {
    // TODO: don't do anything if we're already at MAX_CAPACITY
    int oldCapacity = oldTable.length;
    @SuppressWarnings("unchecked") // Arrays and generics don't get along.
    Node<K, V>[] newTable = new Node[oldCapacity * 2];
    AvlIterator<K, V> iterator = new AvlIterator<>();
    AvlBuilder<K, V> leftBuilder = new AvlBuilder<>();
    AvlBuilder<K, V> rightBuilder = new AvlBuilder<>();

    // Split each tree into two trees.
    for (int i = 0; i < oldCapacity; i++) {
      Node<K, V> root = oldTable[i];
      if (root == null) {
        continue;
      }

      // Compute the sizes of the left and right trees.
      iterator.reset(root);
      int leftSize = 0;
      int rightSize = 0;
      for (Node<K, V> node; (node = iterator.next()) != null; ) {
        if ((node.hash & oldCapacity) == 0) {
          leftSize++;
        } else {
          rightSize++;
        }
      }

      // Split the tree into two.
      leftBuilder.reset(leftSize);
      rightBuilder.reset(rightSize);
      iterator.reset(root);
      for (Node<K, V> node; (node = iterator.next()) != null; ) {
        if ((node.hash & oldCapacity) == 0) {
          leftBuilder.add(node);
        } else {
          rightBuilder.add(node);
        }
      }

      // Populate the enlarged array with these new roots.
      newTable[i] = leftSize > 0 ? leftBuilder.root() : null;
      newTable[i + oldCapacity] = rightSize > 0 ? rightBuilder.root() : null;
    }
    return newTable;
  }
Returns a new array containing the same nodes as {@code oldTable}, but with
twice as many trees, each of (approximately) half the previous size.
lottie/src/main/java/com/airbnb/lottie/parser/moshi/LinkedHashTreeMap.java