replaceParentChild = (
  blockMap: BlockMap,
  parentKey: string,
  existingChildKey: string,
  newChildKey: string,
): BlockMap => {
  const parent = blockMap.get(parentKey);
  const newChild = blockMap.get(newChildKey);
  invariant(
    parent != null && newChild != null,
    'parent & child should exist in the block map',
  );
  const existingChildren = parent.getChildKeys();
  const newBlocks: {[string]: $FlowFixMe} = {};
  newBlocks[parentKey] = parent.merge({
    children: existingChildren.set(
      existingChildren.indexOf(existingChildKey),
      newChildKey,
    ),
  });
  newBlocks[newChildKey] = newChild.merge({
    parent: parentKey,
  });
  return blockMap.merge(newBlocks);
}
This is a utility method for replacing B by C as a child of A, ensuring
that parent <-> child connections between A & C are correctly mirrored

The block map returned by this method may not be a valid tree (siblings are
unaffected)