docs: public boolean optimizeChildrenBlocks( NodeKey key,
                                             EditableDocument document,
                                             int targetCountPerBlock,
                                             int tolerance ) {
          if (document == null) {
              document = edit(key.toString());
              if (document == null) {
                  return false;
              }
          }
          EditableArray children = document.getArray(CHILDREN);
          if (children == null) {
              // There are no children to optimize
              return false;
          }
  
          // Get the children info
          EditableDocument info = document.getDocument(CHILDREN_INFO);
          boolean selfContained = true;
          if (info != null) {
              selfContained = !info.containsField(NEXT_BLOCK);
          }
  
          boolean changed = false;
          if (selfContained) {
              // This is a self-contained block; we only need to do something if the child count is larger than target +/- tolerance
              int total = children.size();
              if (total < targetCountPerBlock + tolerance) {
                  // The number of children is small enough ...
                  return false;
              }
              // Otherwise, there are more children than our target + tolerance, so we need to split the children ...
              splitChildren(key, document, children, targetCountPerBlock, tolerance, true, null);
              changed = true;
          } else {
              assert info != null;
              // This is not self-contained; there are already at least two blocks.
              // Go through each block, and either split it, merge it with the previous block, or leave it.
              EditableDocument doc = document;
              NodeKey docKey = key;
              while (doc != null) {
                  EditableDocument docInfo = doc.getDocument(CHILDREN_INFO);
                  String nextKey = docInfo != null ? docInfo.getString(NEXT_BLOCK) : null;
                  children = doc.getArray(CHILDREN);
                  int count = children.size();
                  boolean isFirst = doc == document;
                  if (count > (targetCountPerBlock + tolerance)) {
                      // This block is too big, so we should split it into multiple blocks...
                      splitChildren(docKey, doc, children, targetCountPerBlock, tolerance, isFirst, nextKey);
                      changed = true;
                  } else if (count < (targetCountPerBlock - tolerance) && nextKey != null) {
                      // This block is too small, so always combine it with the next block, if there is one
                      // (even if that makes the next block too big, since it will be split in a later pass).
                      // Note that since we're only splitting if there is a next block, a last block that
                      // is too small will be left untouched. At this time, we think this is okay.
                      nextKey = mergeChildren(docKey, doc, children, isFirst, nextKey);
                      changed = true;
  
                      if (nextKey == null) {
                          // We merged the last block into this document, so we need to change the pointer in 'document'
                          // to be this doc ...
                          info.setString(LAST_BLOCK, docKey.toString());
                      }
                  }
                  // Otherwise, this block is just right
  
                  // Find the next block ...
                  if (nextKey != null) {
                      doc = edit(nextKey);
                      docKey = new NodeKey(nextKey);
                  } else {
                      doc = null;
                  }
              }
          }
          return changed;
      }