protected function applyParameters($query)
    {
        $this->storeGlobalSettings();

        $strategies = $this->buildStrategies();

        foreach ($this->data->getApplicableAttributes() as $parameterName) {

            // should we skip it no matter what?
            if ($this->isParameterIgnored($parameterName)) continue;

            // get the value for the filter parameter
            // and if it is empty, we're not filtering by it and should skip it
            $parameterValue = $this->data->getParameterValue($parameterName);

            if ($this->isParameterValueUnset($parameterName, $parameterValue)) continue;


            // find the strategy to be used for applying the filter for this parameter
            // then normalize the strategy so that we can call_user_func on it

            $strategy = isset($strategies[$parameterName]) ? $strategies[$parameterName] : null;

            // is it a global setting, not a normal parameter? skip it
            if ($strategy === static::SETTING) continue;


            if (is_a($strategy, ParameterFilterInterface::class)) {

                $strategy = [ $strategy, 'apply' ];

            } elseif (is_null($strategy)) {
                // default, let it be handled by applyParameter

                $strategy = [ $this, 'applyParameter' ];

            } elseif ( ! is_callable($strategy) && ! is_array($strategy)) {

                throw new ParameterStrategyInvalidException(
                    "Invalid strategy defined for parameter '{$parameterName}',"
                    . " must be ParameterFilterInterface, classname, callable or null"
                );
            }

            // apply the strategy
            call_user_func_array($strategy, [ $parameterName, $parameterValue, $query, $this ]);
        }
    }