public function structureVal($val, $options = [])
    {
        if ($val === null) {
            return ($this->multiple() ? [] : null);
        }

        $metadata = clone $this->structureMetadata();

        if ($options instanceof MetadataInterface) {
            $metadata->merge($options);
        } elseif ($options === null) {
            $options = [];
        } elseif (is_array($options)) {
            if (isset($options['metadata'])) {
                $metadata->merge($options['metadata']);
            }
        } else {
            throw new InvalidArgumentException(sprintf(
                'Structure value options must to be an array or an instance of %2$s, received %1$s',
                is_object($options) ? get_class($options) : gettype($options),
                StructureMetadata::class
            ));
        }

        $defaultData = [];
        if (isset($options['default_data'])) {
            if (is_bool($options['default_data'])) {
                $withDefaultData = $options['default_data'];
                if ($withDefaultData) {
                    $defaultData = $metadata->defaultData();
                }
            } elseif (is_array($options['default_data'])) {
                $withDefaultData = true;
                $defaultData     = $options['default_data'];
            }
        }

        $val = $this->parseVal($val);

        if ($this->multiple()) {
            $entries = [];
            foreach ($val as $v) {
                $entries[] = $this->createStructureModelWith($metadata, $defaultData, $v);
            }

            return $entries;
        } else {
            return $this->createStructureModelWith($metadata, $defaultData, $val);
        }
    }