public function beforeSave(Event $event, EntityInterface $entity)
    {
        $isNew = $entity->isNew();
        $config = $this->getConfig();
        $parent = $entity->get($config['parent']);
        $primaryKey = $this->_getPrimaryKey();
        $dirty = $entity->isDirty($config['parent']);
        $level = $config['level'];

        if ($parent && $entity->get($primaryKey) == $parent) {
            throw new RuntimeException("Cannot set a node's parent as itself");
        }

        if ($isNew && $parent) {
            $parentNode = $this->_getNode($parent);
            $edge = $parentNode->get($config['right']);
            $entity->set($config['left'], $edge);
            $entity->set($config['right'], $edge + 1);
            $this->_sync(2, '+', ">= {$edge}");

            if ($level) {
                $entity->set($level, $parentNode[$level] + 1);
            }

            return;
        }

        if ($isNew && !$parent) {
            $edge = $this->_getMax();
            $entity->set($config['left'], $edge + 1);
            $entity->set($config['right'], $edge + 2);

            if ($level) {
                $entity->set($level, 0);
            }

            return;
        }

        if (!$isNew && $dirty && $parent) {
            $this->_setParent($entity, $parent);

            if ($level) {
                $parentNode = $this->_getNode($parent);
                $entity->set($level, $parentNode[$level] + 1);
            }

            return;
        }

        if (!$isNew && $dirty && !$parent) {
            $this->_setAsRoot($entity);

            if ($level) {
                $entity->set($level, 0);
            }
        }
    }