protected function getTreeRepositionData($referenceNode, $nodeWidth, $position = self::LOCATION_BEFORE)
    {
        // Make sure the reference an object with a left and right id.
        if (!is_object($referenceNode) || !(isset($referenceNode->lft) && isset($referenceNode->rgt))) {
            throw new \InvalidArgumentException('Left and right id not exists');
        }

        // A valid node cannot have a width less than 2.
        if ($nodeWidth < 2) {
            return false;
        }

        $k = $this->getKeyName();
        $data = new \stdClass();

        // Run the calculations and build the data object by reference position.
        switch ($position) {
            case static::LOCATION_FIRST_CHILD:
                $data->left_where = 'lft > ' . $referenceNode->lft;
                $data->right_where = 'rgt >= ' . $referenceNode->lft;

                $data->new_lft = $referenceNode->lft + 1;
                $data->new_rgt = $referenceNode->lft + $nodeWidth;
                $data->new_parent_id = $referenceNode->$k;
                $data->new_level = $referenceNode->level + 1;
                break;

            case static::LOCATION_LAST_CHILD:
                $data->left_where = 'lft > ' . ($referenceNode->rgt);
                $data->right_where = 'rgt >= ' . ($referenceNode->rgt);

                $data->new_lft = $referenceNode->rgt;
                $data->new_rgt = $referenceNode->rgt + $nodeWidth - 1;
                $data->new_parent_id = $referenceNode->$k;
                $data->new_level = $referenceNode->level + 1;
                break;

            case static::LOCATION_BEFORE:
                $data->left_where = 'lft >= ' . $referenceNode->lft;
                $data->right_where = 'rgt >= ' . $referenceNode->lft;

                $data->new_lft = $referenceNode->lft;
                $data->new_rgt = $referenceNode->lft + $nodeWidth - 1;
                $data->new_parent_id = $referenceNode->parent_id;
                $data->new_level = $referenceNode->level;
                break;

            default:
            case static::LOCATION_AFTER:
                $data->left_where = 'lft > ' . $referenceNode->rgt;
                $data->right_where = 'rgt > ' . $referenceNode->rgt;

                $data->new_lft = $referenceNode->rgt + 1;
                $data->new_rgt = $referenceNode->rgt + $nodeWidth;
                $data->new_parent_id = $referenceNode->parent_id;
                $data->new_level = $referenceNode->level;
                break;
        }

        return $data;
    }