void YogaLayoutableShadowNode::yogaNodeCloneCallbackConnector(YGNode *oldYogaNode, YGNode *newYogaNode, YGNode *parentYogaNode, int childIndex) {
  // We have only raw pointer to the parent shadow node, but that's enough for now.
  YogaLayoutableShadowNode *parentShadowNodeRawPtr = (YogaLayoutableShadowNode *)parentYogaNode->getContext();
  assert(parentShadowNodeRawPtr);

  // Old child shadow node already exists but we have only raw pointer to it...
  YogaLayoutableShadowNode *oldShadowNodeRawPtr = (YogaLayoutableShadowNode *)oldYogaNode->getContext();
  assert(oldShadowNodeRawPtr);

  // ... but we have to address this by `shared_ptr`. We cannot create a new `shared_ptr` for it because we will end up with two shared pointers to
  // single object which will cause preluminary destroyng the object.
  // Another approaches to consider:
  //  * Create a new `shared_ptr` with empty deleter.
  //  * Using `childIndex` to find exact node.
  SharedLayoutableShadowNode oldShadowNode = nullptr;
  for (auto child : parentShadowNodeRawPtr->getChildren()) {
    if (child.get() == oldShadowNodeRawPtr) {
      oldShadowNode = child;
      break;
    }
  }

  assert(oldShadowNode);

  // The new one does not exist yet. So, we have to clone and replace this using `cloneAndReplaceChild`.
  SharedYogaLayoutableShadowNode newShadowNode =
    std::dynamic_pointer_cast<const YogaLayoutableShadowNode>(parentShadowNodeRawPtr->cloneAndReplaceChild(oldShadowNode));
  assert(newShadowNode);

  // And finally, we have to replace underline yoga node with the new one provided by Yoga.
  newYogaNode->setContext((void *)newShadowNode.get());
  newShadowNode->yogaNode_ = std::shared_ptr<YGNode>(newYogaNode);
}
void YogaLayoutableShadowNode::appendChild(SharedYogaLayoutableShadowNode child) {
  ensureUnsealed();

  auto yogaNodeRawPtr = &yogaNode_;
  auto childYogaNodeRawPtr = &child->yogaNode_;
  yogaNodeRawPtr->insertChild(childYogaNodeRawPtr, yogaNodeRawPtr->getChildrenCount());

  if (childYogaNodeRawPtr->getOwner() == nullptr) {
    child->ensureUnsealed();
    childYogaNodeRawPtr->setOwner(yogaNodeRawPtr);
  }
}
void YogaLayoutableShadowNode::setYogaNodeChildrenBasedOnShadowNodeChildren(YGNode *yogaNodeRawPtr, const SharedShadowNodeSharedList &children) {
  auto yogaNodeChildren = YGVector();

  for (const SharedShadowNode &shadowNode : *children) {
    const SharedYogaLayoutableShadowNode yogaLayoutableShadowNode = std::dynamic_pointer_cast<const YogaLayoutableShadowNode>(shadowNode);

    if (!yogaLayoutableShadowNode) {
      continue;
    }

    auto &&childYogaNodeRawPtr = &yogaLayoutableShadowNode->yogaNode_;

    yogaNodeChildren.push_back(childYogaNodeRawPtr);

    if (childYogaNodeRawPtr->getOwner() == nullptr) {
      yogaLayoutableShadowNode->ensureUnsealed();
      childYogaNodeRawPtr->setOwner(yogaNodeRawPtr);
    }
  }

  yogaNodeRawPtr->setChildren(yogaNodeChildren);
}
void YogaLayoutableShadowNode::appendChild(SharedYogaLayoutableShadowNode child) {
  ensureUnsealed();

  auto yogaNodeRawPtr = &yogaNode_;
  auto childYogaNodeRawPtr = &child->yogaNode_;

  if (childYogaNodeRawPtr->getOwner() != nullptr) {
    child = std::static_pointer_cast<const YogaLayoutableShadowNode>(cloneAndReplaceChild(child));
    childYogaNodeRawPtr = &child->yogaNode_;
  }

  child->ensureUnsealed();
  childYogaNodeRawPtr->setOwner(yogaNodeRawPtr);

  yogaNodeRawPtr->insertChild(childYogaNodeRawPtr, yogaNodeRawPtr->getChildren().size());
}