public function addChild($parent, $child)
{
if (!isset($this->items[$parent->name], $this->items[$child->name])) {
throw new InvalidParamException("Either '{$parent->name}' or '{$child->name}' does not exist.");
}
if ($parent->name === $child->name) {
throw new InvalidParamException("Cannot add '{$parent->name} ' as a child of itself.");
}
if ($parent instanceof Permission && $child instanceof Role) {
throw new InvalidParamException('Cannot add a role as a child of a permission.');
}
if ($this->detectLoop($parent, $child)) {
throw new InvalidCallException("Cannot add '{$child->name}' as a child of '{$parent->name}'. A loop has been detected.");
}
if (isset($this->children[$parent->name][$child->name])) {
throw new InvalidCallException("The item '{$parent->name}' already has a child '{$child->name}'.");
}
$this->children[$parent->name][$child->name] = $this->items[$child->name];
$this->saveItems();
return true;
}