{@inheritdoc}

@throws \InvalidArgumentException
@throws \Symfony\Component\OptionsResolver\Exception\ExceptionInterface|\InvalidArgumentException
@throws \RuntimeException
487489
final public function getQuery(array $parameters = [])
    {
        $parameters = $this->getOptionsResolver()->resolve($parameters);
        $query = $this->buildQuery();

        $sortDefinitions = $parameters['sort'];
        if (!is_array($sortDefinitions)) {
            $sortDefinitions = [$sortDefinitions];
        }

        $query->query = $this->getQueryCriterion($parameters);
        $query->filter = $this->resolveFilterCriteria($parameters);
        $query->facetBuilders = $this->getFacetBuilders($parameters);
        $query->sortClauses = $this->getSortClauses($sortDefinitions);
        $query->limit = $parameters['limit'];
        $query->offset = $parameters['offset'];

        return $query;
    }
1241988
private function configureOptions(OptionsResolver $resolver, $region)
    {
        if (isset(GeoData::$list[$region])) {
            $locales = GeoData::$list[$region];
        } else {
            throw new InvalidOptionsException(
                sprintf(
                    'The option "region" with value "%s" is invalid. Accepted values are: "%s".',
                    $region,
                    implode('", "', array_keys(GeoData::$list))
                )
            );
        }

        $resolver->setRequired(['apiKey', 'apiSecret', 'region', 'locale'])
                 ->setAllowedTypes('apiKey', 'string')
                 ->setAllowedTypes('apiSecret', 'string')
                 ->setAllowedTypes('region', 'string')
                 ->setAllowedValues('region', array_keys(GeoData::$list))
                 ->setAllowedTypes('locale', 'string')
                 ->setAllowedValues('locale', $locales);
    }
1326337
private function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'cache_lifetime' => 86400 * 30, // 30 days
            'default_ttl' => 0,
            //Deprecated as of v1.3, to be removed in v2.0. Use respect_response_cache_directives instead
            'respect_cache_headers' => null,
            'hash_algo' => 'sha1',
            'methods' => ['GET', 'HEAD'],
            'respect_response_cache_directives' => ['no-cache', 'private', 'max-age', 'no-store'],
            'cache_key_generator' => null,
            'cache_listeners' => [],
        ]);

        $resolver->setAllowedTypes('cache_lifetime', ['int', 'null']);
        $resolver->setAllowedTypes('default_ttl', ['int', 'null']);
        $resolver->setAllowedTypes('respect_cache_headers', ['bool', 'null']);
        $resolver->setAllowedTypes('methods', 'array');
        $resolver->setAllowedTypes('cache_key_generator', ['null', 'Http\Client\Common\Plugin\Cache\Generator\CacheKeyGenerator']);
        $resolver->setAllowedValues('hash_algo', hash_algos());
        $resolver->setAllowedValues('methods', function ($value) {
            /* RFC7230 sections 3.1.1 and 3.2.6 except limited to uppercase characters. */
            $matches = preg_grep('/[^A-Z0-9!#$%&\'*+\-.^_`|~]/', $value);

            return empty($matches);
        });
        $resolver->setAllowedTypes('cache_listeners', ['array']);

        $resolver->setNormalizer('respect_cache_headers', function (Options $options, $value) {
            if (null !== $value) {
                @trigger_error('The option "respect_cache_headers" is deprecated since version 1.3 and will be removed in 2.0. Use "respect_response_cache_directives" instead.', E_USER_DEPRECATED);
            }

            return null === $value ? true : $value;
        });

        $resolver->setNormalizer('respect_response_cache_directives', function (Options $options, $value) {
            if (false === $options['respect_cache_headers']) {
                return [];
            }

            return $value;
        });
    }
856035
public function buildForm(FormBuilderInterface $builder, array $options): void
    {
        $this->assertOptionsAreValid($options);

        foreach ($options['options'] as $i => $option) {
            if (!$option instanceof ProductOptionInterface) {
                throw new InvalidConfigurationException(
                    sprintf('Each object passed as option list must implement "%s"', ProductOptionInterface::class)
                );
            }

            $builder->add((string) $option->getCode(), ProductOptionValueChoiceType::class, [
                'label' => $option->getName() ?: $option->getCode(),
                'option' => $option,
                'property_path' => '[' . $i . ']',
                'block_name' => 'entry',
            ]);
        }
    }
414801
private function resolveConfiguration(array $options = []): void
    {
        $resolver = new OptionsResolver();
        $this->configureOptions($resolver);
        $options = $resolver->resolve($options);
        $this->userAgentPrefix = $options[static::CONFIG_USER_AGENT_PREFIX];
        $this->httpClientBuilder = $options[static::CONFIG_HTTP_CLIENT_BUILDER] ?: new Builder();
        $this->uriFactory = $options[static::CONFIG_URI_FACTORY] ?: UriFactoryDiscovery::find();
        $this->requestFactory = $options[static::CONFIG_REQUEST_FACTORY] ?: MessageFactoryDiscovery::find();
        $this->journal = $options[static::CONFIG_JOURNAL] ?: new Journal();
        $this->errorFormatter = $options[static::CONFIG_ERROR_FORMATTER];
        $this->retryPluginConfig = $options[static::CONFIG_RETRY_PLUGIN_CONFIG];
    }
591535
public function configureOptionsResolver(OptionsResolver $resolver)
    {
        parent::configureOptionsResolver($resolver);
        $resolver->setRequired([
            self::OPTION_NOSQL_DRIVER,
            self::OPTION_COLLECTION_PREFIX,
            self::OPTION_COLLECTION_NAME,
            self::OPTION_METHOD
        ]);

        $resolver->setAllowedTypes(self::OPTION_COLLECTION_NAME, ['string']);
        $resolver->setAllowedTypes(self::OPTION_COLLECTION_PREFIX, ['string']);
        $resolver->setAllowedTypes(self::OPTION_NOSQL_DRIVER, ['string']);
        $resolver->setAllowedTypes(self::OPTION_METHOD, ['string']);
    }
1009172
public function resolve($input)
    {
        if (!\is_array($input)) {
            $input = [$input];
        }

        if (!isset($input[0]) || !isset($input[1])) {
            $optionResolver = new OptionsResolver();
            $optionResolver->setDefaults([null, []]);
            $input = $optionResolver->resolve($input);
        }

        $alias = $input[0];
        $funcArgs = $input[1];

        $solution = $this->getSolution($alias);

        if (null === $solution) {
            throw new UnresolvableException($this->unresolvableMessage($alias));
        }

        $options = $this->getSolutionOptions($alias);
        $func = [$solution, $options['method']];

        return \call_user_func_array($func, $funcArgs);
    }
1223502
public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setRequired(
            [
                'family',
            ]
        );
        $resolver->setAllowedTypes('family', ['string', FamilyInterface::class]);
        $resolver->setDefaults(
            [
                'repository' => null,
                'ignore_missing' => true,
            ]
        );
        $resolver->setAllowedTypes('repository', ['NULL', DataRepository::class]);
        $resolver->setAllowedTypes('ignore_missing', ['bool']);

        /** @noinspection PhpUnusedParameterInspection */
        $resolver->setNormalizer(
            'family',
            function (Options $options, $value) {
                if ($value instanceof FamilyInterface) {
                    return $value;
                }

                return $this->familyRegistry->getFamily($value);
            }
        );
        $resolver->setNormalizer(
            'repository',
            function (Options $options, $value) {
                if ($value instanceof DataRepository) {
                    return $value;
                }
                /** @var FamilyInterface $family */
                $family = $options['family'];

                return $this->entityManager->getRepository($family->getDataClass());
            }
        );
    }
132657
public function setDefaultOptions(OptionsResolver $resolver)
    {
        foreach ($this->middlewares as $middleware) {
            if ($middleware instanceof ConfigurableInterface) {
                $middleware->setDefaultOptions($resolver);
            }
        }
    }
947250
private function getOptionsResolver()
    {
        // TODO Use/Merge ConfigurationBuilder options resolver.
        if (!$this->optionsResolver) {
            $resolver = new OptionsResolver();

            $resolver
                ->setRequired(['namespace', 'id', 'classes'])
                ->setDefaults([
                    'name'        => function (Options $options) {
                        return Inflector::camelize($options['id']);
                    },
                    'parent_id'   => null,
                    'event'       => null,
                    'templates'   => null,
                    'translation' => null,
                ])
                ->setAllowedTypes('namespace', 'string')
                ->setAllowedTypes('id', 'string')
                ->setAllowedTypes('name', 'string')
                ->setAllowedTypes('parent_id', ['null', 'string'])
                ->setAllowedTypes('classes', 'array')
                ->setAllowedTypes('event', ['null', 'string', 'array'])
                ->setAllowedTypes('templates', ['null', 'string', 'array'])
                ->setAllowedTypes('translation', ['null', 'array']);


            // Classes option
            $classesResolver = new OptionsResolver();
            $classesResolver
                ->setRequired(['entity'])
                ->setDefaults([
                    'form_type'  => null, // @TODO/WARNING no longer required (behavior refactoring)
                    'repository' => null,
                ])
                ->setAllowedTypes('entity', 'string')
                ->setAllowedTypes('repository', ['null', 'string'])
                ->setAllowedTypes('form_type', ['null', 'string']); // @TODO/WARNING no longer required (behavior refactoring)

            $resolver
                ->setNormalizer('classes', function (Options $options, $value) use ($classesResolver) {
                    foreach ($value as $class) {
                        if ($class && !class_exists($class)) {
                            throw new InvalidOptionsException(sprintf("Class '%s' does not exists.", $class));
                        }
                    }

                    $entity = $value['entity'];
                    if (null !== $options['translation'] && !is_subclass_of($entity, TranslatableInterface::class)) {
                        throw new InvalidOptionsException(sprintf(
                            "Class '%s' must implements '%s'.",
                            $entity,
                            TranslatableInterface::class));
                    }

                    $repository = array_key_exists('repository', $value) ? $value['repository'] : null;
                    if (null === $repository) {
                        $value['repository'] = null !== $options['translation']
                            ? TranslatableResourceRepository::class
                            : ResourceRepository::class;
                    } elseif (null !== $options['translation']) {
                        if (!is_subclass_of($repository, TranslatableResourceRepositoryInterface::class)) {
                            throw new InvalidOptionsException(sprintf(
                                "Class '%s' must implements '%s'.",
                                $repository,
                                TranslatableResourceRepositoryInterface::class
                            ));
                        }
                    } else {
                        if (!is_subclass_of($repository, ResourceRepositoryInterface::class)) {
                            throw new InvalidOptionsException(sprintf(
                                "Class '%s' must implements '%s'.",
                                $repository,
                                ResourceRepositoryInterface::class
                            ));
                        }
                    }

                    return $classesResolver->resolve($value);
                });


            // Translation option
            $translationResolver = new OptionsResolver();
            $translationResolver
                ->setRequired(['entity', 'fields'])
                ->setDefault('repository', null)
                ->setAllowedTypes('entity', 'string')
                ->setAllowedTypes('fields', 'array')
                ->setAllowedTypes('repository', ['null', 'string'])
                ->setAllowedValues('entity', function ($class) {
                    if (!class_exists($class)) {
                        throw new InvalidOptionsException(sprintf("Class '%s' does not exists.", $class));
                    }
                    if (!is_subclass_of($class, TranslationInterface::class)) {
                        throw new InvalidOptionsException(sprintf("Class '%s' must implements '%s'.", $class, TranslationInterface::class));
                    }

                    return true;
                })
                ->setAllowedValues('fields', function ($fields) {
                    if (empty($fields)) {
                        throw new InvalidOptionsException("Translatable fields cannot be empty.");
                    }

                    return true;
                })
                ->setAllowedValues('repository', function ($class) {
                    if (null !== $class && !class_exists($class)) {
                        throw new InvalidOptionsException(sprintf("Class '%s' does not exists.", $class));
                    }

                    return true;
                });

            /** @noinspection PhpUnusedParameterInspection */
            $resolver->setNormalizer('translation', function (Options $options, $value) use ($translationResolver) {
                if (is_array($value)) {
                    return $translationResolver->resolve($value);
                }

                return $value;
            });


            // Event option
            $eventResolver = new OptionsResolver();
            $eventResolver
                ->setRequired(['class'])
                ->setDefaults([
                    'class'    => $this->defaultEventClass,
                    'priority' => 0,
                ])
                ->setAllowedTypes('class', 'string')
                ->setAllowedTypes('priority', 'int');

            /** @noinspection PhpUnusedParameterInspection */
            $resolver->setNormalizer('event', function (Options $options, $value) use ($eventResolver) {
                if (is_string($value)) {
                    $value = ['class' => $value];
                }

                $value = $eventResolver->resolve((array)$value);

                if (!is_subclass_of($value['class'], ResourceEventInterface::class)) {
                    throw new InvalidOptionsException(sprintf(
                        "Class '%s' must implements '%s'.",
                        $value['class'],
                        ResourceEventInterface::class
                    ));
                }

                return $value;
            });


            // Templates option
            /** @noinspection PhpUnusedParameterInspection */
            $resolver->setNormalizer('templates', function (Options $options, $value) {
                return $this->buildTemplateList($value);
            });


            $this->optionsResolver = $resolver;
        }

        return $this->optionsResolver;
    }
624736
protected function getOptionsResolver($uri, array &$routeOptions, ProtocolInterface $protocol, $mode)
    {
        $optionsResolver = new OptionsResolver();
        $protocol->configureOptionsResolver($optionsResolver);

        $consumer = array_key_exists(Protocol::OPTION_CONSUMER, $routeOptions) ? $routeOptions[Protocol::OPTION_CONSUMER] : $protocol->getDefaultConsumer();
        $producer = array_key_exists(Protocol::OPTION_PRODUCER, $routeOptions) ? $routeOptions[Protocol::OPTION_PRODUCER] : $protocol->getDefaultProducer();
        $handler = array_key_exists(Protocol::OPTION_HANDLER, $routeOptions) ? $routeOptions[Protocol::OPTION_HANDLER] : $protocol->getDefaultHandler();

        // Check Consumer
        if (self::MODE_CONSUME == $mode && $consumer) {
            if ($consumer instanceof ConsumerInterface) {
                if ($consumer instanceof ConfigurableInterface) {
                    $consumer->configureOptionsResolver($optionsResolver);
                }
            } else {
                throw new \RuntimeException(
                    'Consumers must implement ConsumerInterface. Found consumer class for endpoint with URI: '
                    .$uri
                    .' that does not implement ConsumerInterface.'
                );
            }
        }

        // Check Producer
        if (self::MODE_PRODUCE == $mode && $producer) {
            if ($producer instanceof ProducerInterface) {
                if ($producer instanceof ConfigurableInterface) {
                    $producer->configureOptionsResolver($optionsResolver);
                }
            } else {
                throw new \RuntimeException(
                    'Producers must implement ProducerInterface. Found producer class for endpoint with URI: '
                    .$uri
                    .' that does not implement ProducerInterface.'
                );
            }
        }

        // Check Handler
        if ($handler) {
            if ($handler instanceof HandlerInterface) {
                if ($handler instanceof ConfigurableInterface) {
                    $handler->configureOptionsResolver($optionsResolver);
                }
            } else {
                throw new \RuntimeException(
                    'Handlers must implement HandlerInterface. Found handler class for endpoint with URI: '
                    .$uri
                    .' that does not implement HandlerInterface.'
                );
            }
        }

        $this->defineInternalKeys($optionsResolver);

        return $optionsResolver;
    }
951523
public function getExecOptionsResolver()
    {
        if (null === $this->execOptionsResolver) {
            if (null !== $this->parent) {
                $this->execOptionsResolver = clone $this->parent->getExecOptionsResolver();
            } else {
                $this->execOptionsResolver = new OptionsResolver();
            }

            $this->innerType->setExecOptions($this->execOptionsResolver);

            foreach ($this->typeExtensions as $extension) {
                $extension->setExecOptions($this->execOptionsResolver);
            }
        }

        return $this->execOptionsResolver;
    }
151110
public function trash(EntityInterface $entity, array $options = [])
    {
        $primaryKey = (array)$this->_table->getPrimaryKey();

        foreach ($primaryKey as $field) {
            if (!$entity->has($field)) {
                throw new RuntimeException();
            }
        }

        foreach ($this->_table->associations() as $association) {
            if ($this->_isRecursable($association, $this->_table)) {
                $association->cascadeDelete($entity, ['_primary' => false] + $options);
            }
        }

        $data = [$this->getTrashField(false) => new Time()];
        $entity->set($data, ['guard' => false]);

        if ($this->_table->save($entity, $options)) {
            return true;
        }

        return false;
    }
209678
protected function init($options)
    {
        foreach ($options as $parameterName => $parameterValue) {
            if ( ! isset ($this->{$parameterName})) {
                throw new \Exception ("The parameter $parameterName is not a valid parameter name");
            }

            if (gettype($this->{$parameterName}) != gettype($parameterValue)) {
                throw new \Exception ("The parameter value type passed for $parameterName is not an accepted type, only " . gettype($this->{$parameterName}));
            }

            $this->{'set' . ucfirst($parameterName)}($parameterValue);
        }
    }
738898
public function getOption($key)
    {
        if (!$this->hasOption($key)) {
            throw new Exception\InvalidArgumentException(
                "Option " . $key . " not defined on "
                . $this->reflection->getClassName() . "::$"
                . $this->name . "!"
            );
        }
        return $this->options[$key];
    }
111563
public function configureOptions(OptionsResolver $resolver)
    {
        parent::configureOptions($resolver);
        $resolver->setRequired(
            [
                'attribute',
            ]
        );
        $resolver->setAllowedTypes('attribute', ['string', AttributeInterface::class]);
        $resolver->setNormalizer(
            'attribute',
            function (Options $options, $value) {
                /** @var FamilyInterface $family */
                $family = $options['family'];
                if ($value instanceof AttributeInterface) {
                    if (!$family->hasAttribute($value->getCode())) {
                        throw new \UnexpectedValueException(
                            "Family {$family->getCode()} has no attribute named {$value->getCode()}"
                        );
                    }

                    return $value;
                }

                return $family->getAttribute($value);
            }
        );
    }
1178534
private function configureStartControlProperties(OptionsResolver $resolver)
    {
        $resolver->setDefined('autostart')
            ->setAllowedTypes('autostart', 'bool');

        $resolver
            ->setDefined('autorestart')
            ->setAllowedTypes('autorestart', ['bool', 'string'])
            ->setAllowedValues('autorestart', [true, false, 'true', 'false', 'unexpected'])
            ->setNormalizer('autorestart', function (Options $options, $value) {
                return (is_bool($value) or $value === 'unexpected') ? $value : ($value === 'true' ? true : false);
            });

        $resolver->setDefined('startsecs')
            ->setAllowedTypes('startsecs', 'int');

        $resolver->setDefined('startretries')
            ->setAllowedTypes('startretries', 'int');
    }