private function resolveOptions(array $options): array
    {
        $optionsResolver = new OptionsResolver();

        $optionsResolver->setDefault('default_value', null);
        $optionsResolver->setDefault('required', false);
        $optionsResolver->setDefault('label', null);
        $optionsResolver->setDefault('groups', []);
        $optionsResolver->setDefault('constraints', []);

        if ($this->type instanceof ParameterTypeInterface) {
            $this->type->configureOptions($optionsResolver);
        }

        $this->configureOptions($optionsResolver);

        $optionsResolver->setRequired(['required', 'default_value', 'label', 'groups', 'constraints']);

        $optionsResolver->setAllowedTypes('required', 'bool');
        $optionsResolver->setAllowedTypes('label', ['string', 'null', 'bool']);
        $optionsResolver->setAllowedTypes('groups', 'array');
        $optionsResolver->setAllowedTypes('constraints', 'array');

        // @deprecated Replace with "string[]" allowed type when support for Symfony 2.8 ends
        $optionsResolver->setAllowedValues(
            'groups',
            static function (array $groups): bool {
                foreach ($groups as $group) {
                    if (!is_string($group)) {
                        return false;
                    }
                }

                return true;
            }
        );

        $optionsResolver->setAllowedValues(
            'constraints',
            function (array $constraints): bool {
                return $this->validateConstraints($constraints);
            }
        );

        $optionsResolver->setNormalizer(
            'groups',
            function (Options $options, array $value): array {
                if (!$this->parentBuilder instanceof ParameterBuilderInterface) {
                    return $value;
                }

                if (!$this->parentBuilder->getType() instanceof CompoundParameterTypeInterface) {
                    return $value;
                }

                return $this->parentBuilder->getGroups();
            }
        );

        $optionsResolver->setAllowedValues(
            'label',
            static function ($value): bool {
                if (!is_bool($value)) {
                    return true;
                }

                return $value === false;
            }
        );

        $resolvedOptions = $optionsResolver->resolve($options);

        $this->isRequired = $resolvedOptions['required'];
        $this->defaultValue = $resolvedOptions['default_value'];
        $this->label = $resolvedOptions['label'];
        $this->groups = $resolvedOptions['groups'];
        $this->constraints = $resolvedOptions['constraints'];

        unset(
            $resolvedOptions['required'],
            $resolvedOptions['default_value'],
            $resolvedOptions['label'],
            $resolvedOptions['groups'],
            $resolvedOptions['constraints']
        );

        return $resolvedOptions;
    }