private function makeDefaultArgs(\ReflectionFunctionAbstract $function, array $ruleArgs) {
        $ruleArgs = array_change_key_case($ruleArgs);
        $result = [];

        $pos = 0;
        foreach ($function->getParameters() as $i => $param) {
            $name = strtolower($param->name);

            $reflectedClass = null;
            try {
                $reflectedClass = $param->getClass();
            } catch (\ReflectionException $e) {
                // If the class is not found in the autoloader a reflection exception is thrown.
                // Unless the parameter is optional we will want to rethrow.
                if (!$param->isOptional()) {
                    throw new NotFoundException(
                        "Could not find required constructor param $name in the autoloader.",
                        500,
                        $e
                    );
                }
            }

            if (array_key_exists($name, $ruleArgs)) {
                $value = $ruleArgs[$name];
            } elseif ($reflectedClass && isset($ruleArgs[$pos]) &&
                // The argument is a reference that matches the type hint.
                (($ruleArgs[$pos] instanceof Reference && is_a($this->findRuleClass($ruleArgs[$pos]->getName()), $reflectedClass->getName(), true)) ||
                // The argument is an instance that matches the type hint.
                (is_object($ruleArgs[$pos]) && is_a($ruleArgs[$pos], $reflectedClass->name)))
            ) {
                $value = $ruleArgs[$pos];
                $pos++;
            } elseif ($reflectedClass
                && ($reflectedClass->isInstantiable() || isset($this->rules[$reflectedClass->name]) || array_key_exists($reflectedClass->name, $this->instances))
            ) {
                $value = new DefaultReference($this->normalizeID($reflectedClass->name));
            } elseif (array_key_exists($pos, $ruleArgs)) {
                $value = $ruleArgs[$pos];
                $pos++;
            } elseif ($param->isDefaultValueAvailable()) {
                $value = $param->getDefaultValue();
            } elseif ($param->isOptional()) {
                $value = null;
            } else {
                $value = new RequiredParameter($param);
            }

            $result[$name] = $value;
        }

        return $result;
    }