final public function withAttribute($name, $value = null, bool $inAllElements = false): self
    {
        // insert or update one or more attributes into all elements
        if (is_array($this->data) && $inAllElements === true) {
            foreach ($this->data as $dataKey => $element) {
                if (is_array($name)) {
                    $element = $this->addingAttribute($element, $name, $dataKey);
                    continue;
                }
                if (!is_array($name) && is_callable($value)) {
                    $element->$name = $value($this->rawData[$dataKey]);
                    continue;
                }
                $element->$name = $value;
            }

            return $this;
        } else {
            if ($inAllElements === true) {
                throw new \Exception("The results is not an array");
            }
        }

        if (is_array($name)) {
            foreach ($name as $attributeKey => $attributeValue) {
                if (is_array($this->data)) {
                    $this->data[$attributeKey] = is_callable($attributeValue) ? $attributeValue($this->rawData) : $attributeValue;
                } else {
                    $this->data->$attributeKey = is_callable($attributeValue) ? $attributeValue($this->rawData) : $attributeValue;
                }
            }
            return $this;
        }

        if (is_array($this->data)) {
            $this->data[$name] = is_callable($value) ? $value($this->rawData) : $value;
        } else {
            $this->data->$name = is_callable($value) ? $value($this->rawData) : $value;
        }

        return $this;
    }