protected function applyCast(string $key): void
    {
        $casts = $this->casts();

        if ( ! count($casts) || ! array_key_exists($key, $casts)) {
            return;
        }

        if ( ! isset($this->attributes[ $key ])) {
            $value = null;
        } else {
            $value = $this->attributes[ $key ];
        }

        // If the cast type is a simple scalar, apply it and return
        if (in_array($casts[ $key ], static::SCALAR_CASTS)) {
            $this->attributes[ $key ] = call_user_func([$this, 'castValueAs' . ucfirst($casts[ $key ])], $value);
            return;
        }

        // Otherwise attempt a data object cast
        $dataObjectClass = $casts[ $key ];
        $dataObjectArray = false;

        // If the model is postfixed with [], an array of models is expected
        if (substr($dataObjectClass, -2) === '[]') {
            $dataObjectClass = substr($dataObjectClass, 0, -2);
            $dataObjectArray = true;
        }

        if (null === $value) {
            if ($dataObjectArray) {
                $this->attributes[ $key ] = [];
                return;
            }

            if ($this->castUnsetObjects) {
                $this->attributes[ $key ] = $this->makeNestedDataObject($dataObjectClass, [], $key);
            }
            return;
        }

        if ($dataObjectArray) {

            if (is_array($this->attributes[ $key ])) {

                foreach ($this->attributes[ $key ] as $index => &$item) {

                    if (null === $item && ! $this->castUnsetObjects) {
                        continue;
                    }

                    if ( ! ($item instanceof $dataObjectClass)) {

                        $item = $this->makeNestedDataObject($dataObjectClass, $item ?: [], $key . '.' . $index);
                    }
                }
            }

            unset($item);

            return;
        }

        // Single data object
        if ( ! ($this->attributes[ $key ] instanceof $dataObjectClass)) {
            $this->attributes[ $key ] = $this->makeNestedDataObject(
                $dataObjectClass,
                $this->attributes[ $key ],
                $key
            );
        }
    }